├── .travis.yml ├── .gitignore ├── public ├── github │ ├── github-icons.png │ ├── github-icons-2x.png │ └── button.html └── facebook-channel.php ├── templates ├── stumbleupon │ ├── buttons │ │ └── html.php │ └── script.js ├── twitter │ ├── buttons │ │ ├── html-follow.php │ │ └── html-tweet.php │ └── script.js ├── googleplus │ ├── buttons │ │ └── html.php │ └── script.js ├── pinterest │ ├── buttons │ │ └── html.php │ └── script.js ├── github │ ├── buttons │ │ └── html.php │ └── script.js ├── facebook │ ├── buttons │ │ ├── xbfml.php │ │ └── html5.php │ └── script.js ├── linkedin │ ├── buttons │ │ └── html.php │ └── script.js ├── flattr │ ├── script.js │ └── buttons │ │ └── html.php └── script.js ├── classes └── COI │ └── Social │ ├── LinkedIn.php │ ├── StumbleUpon.php │ ├── GooglePlus.php │ ├── GitHub.php │ ├── Twitter.php │ ├── Pinterest.php │ ├── Flattr.php │ ├── Facebook.php │ ├── Cache.php │ ├── AbstractElement.php │ ├── Compressor.php │ └── Manager.php ├── functions ├── shortcuts.php └── local.php ├── require.php ├── composer.json ├── LICENSE ├── README.md └── include.php /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - 5.3 4 | - 5.4 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | dependencies/ 3 | sftp-config.json 4 | -------------------------------------------------------------------------------- /public/github/github-icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basuke/PHP-Socializer/master/public/github/github-icons.png -------------------------------------------------------------------------------- /templates/stumbleupon/buttons/html.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/github/github-icons-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/basuke/PHP-Socializer/master/public/github/github-icons-2x.png -------------------------------------------------------------------------------- /templates/twitter/buttons/html-follow.php: -------------------------------------------------------------------------------- 1 | Follow @pagesofinterest 4 | -------------------------------------------------------------------------------- /templates/googleplus/buttons/html.php: -------------------------------------------------------------------------------- 1 |
5 | -------------------------------------------------------------------------------- /classes/COI/Social/LinkedIn.php: -------------------------------------------------------------------------------- 1 | &media=&description=" class="pin-it-button" count-layout="">Pin It 2 | -------------------------------------------------------------------------------- /public/facebook-channel.php: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /classes/COI/Social/GooglePlus.php: -------------------------------------------------------------------------------- 1 | ?user=&repo=&type=" 2 | allowtransparency="true" frameborder="0" scrolling="0" width="px" height="px"> 3 | -------------------------------------------------------------------------------- /templates/facebook/buttons/xbfml.php: -------------------------------------------------------------------------------- 1 | 7 | font="" 8 | 9 | data-colorscheme=""> -------------------------------------------------------------------------------- /templates/linkedin/buttons/html.php: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /templates/facebook/buttons/html5.php: -------------------------------------------------------------------------------- 1 |
8 | font="" 9 | 10 | data-colorscheme="">
-------------------------------------------------------------------------------- /templates/github/script.js: -------------------------------------------------------------------------------- 1 | fadeIn): ?> 2 | _socialQueue.push({ 3 | preload: function(f) { 4 | var buttons = document.getElementsByClassName('coi-social-button-name; ?>'); 5 | for (var i = 0; i < buttons.length; i++) { 6 | f.iframeOnload(buttons[i].getElementsByTagName('IFRAME')[0], buttons[i], 'fadeIn; ?>'); 7 | } 8 | } 9 | }); 10 | 11 | -------------------------------------------------------------------------------- /classes/COI/Social/GitHub.php: -------------------------------------------------------------------------------- 1 | type; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /templates/twitter/buttons/html-tweet.php: -------------------------------------------------------------------------------- 1 | 8 | data-related="" 9 | 10 | 11 | data-hashtags="" 12 | 13 | 14 | data-hashtags="" 15 | 16 | data-lang="en">Tweet -------------------------------------------------------------------------------- /functions/shortcuts.php: -------------------------------------------------------------------------------- 1 | name; ?>', 4 | onload: function(f) { 5 | if ('fadeIn; ?>') { 6 | f.awaitRender({ 7 | buttons: document.getElementsByClassName('coi-social-button-name; ?>'), 8 | duration: 'fadeIn; ?>', 9 | isRendered: function(element) { 10 | return element.getElementsByTagName('IFRAME')[0]; 11 | }, 12 | renderedMethod: function(b, d) { 13 | f.iframeOnload(b.getElementsByTagName('IFRAME')[0], b, d); 14 | } 15 | }); 16 | } 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /templates/stumbleupon/script.js: -------------------------------------------------------------------------------- 1 | _socialQueue.push({ 2 | url: '//platform.stumbleupon.com/1/widgets.js', 3 | id: 'name; ?>', 4 | onload: function(f) { 5 | window.STMBLPN.processWidgets(); 6 | if ('fadeIn; ?>') { 7 | f.awaitRender({ 8 | buttons: document.getElementsByClassName('coi-social-button-name; ?>'), 9 | duration: 'fadeIn; ?>', 10 | isRendered: function(element) { 11 | return element.getElementsByTagName('IFRAME')[0]; 12 | }, 13 | renderedMethod: function(b, d) { 14 | f.iframeOnload(b.getElementsByTagName('IFRAME')[0], b, d); 15 | } 16 | }); 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /functions/local.php: -------------------------------------------------------------------------------- 1 | name; ?>', 4 | preload: function(f) { 5 | window.PinIt = window.PinIt || { 6 | loaded:false 7 | }; 8 | if (window.PinIt.loaded) { 9 | return; 10 | } 11 | window.PinIt.loaded = true; 12 | }, 13 | onload: function(f) { 14 | if ('fadeIn; ?>') { 15 | f.awaitRender({ 16 | buttons: document.getElementsByClassName('coi-social-button-name; ?>'), 17 | duration: 'fadeIn; ?>', 18 | isRendered: function(element) { 19 | return element.getElementsByTagName('A')[0]; 20 | } 21 | }); 22 | } 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /classes/COI/Social/Pinterest.php: -------------------------------------------------------------------------------- 1 | =5.3.0" 23 | }, 24 | "autoload": { 25 | "psr-0": { 26 | "COI": "classes/" 27 | }, 28 | "files": [ 29 | "include.php" 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /templates/googleplus/script.js: -------------------------------------------------------------------------------- 1 | _socialQueue.push({ 2 | url: 'https://apis.google.com/js/plusone.js', 3 | id: 'name; ?>', 4 | onload: function(f) { 5 | if ('fadeIn; ?>') { 6 | f.awaitRender({ 7 | buttons: document.getElementsByClassName('coi-social-button-name; ?>'), 8 | duration: 'fadeIn; ?>', 9 | isRendered: function(element) { 10 | return element.firstChild && 11 | element.firstChild.firstChild && 12 | element.firstChild.firstChild.tagName.toUpperCase() === 'IFRAME'; 13 | }, 14 | renderedMethod: function(b, d) { 15 | f.iframeOnload(b.firstChild.firstChild, b, d); 16 | } 17 | }); 18 | } 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /templates/flattr/buttons/html.php: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /classes/COI/Social/Flattr.php: -------------------------------------------------------------------------------- 1 | character which will be converted into newlines (\n). 44 | */ 45 | public $description = null; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /classes/COI/Social/Facebook.php: -------------------------------------------------------------------------------- 1 | isset($_SERVER) ? '//'.$_SERVER['HTTP_HOST'].'/facebook-channel.php' : null 33 | ), $options)); 34 | } 35 | 36 | public function getView() { 37 | switch ($this->type) { 38 | case Type\HTML5: { 39 | return 'html5'; 40 | } 41 | case Type\XBFML: { 42 | return 'xbfml'; 43 | } 44 | } 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Michael Robinson 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the Code of Interest nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL MICHAEL ROBINSON BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /templates/linkedin/script.js: -------------------------------------------------------------------------------- 1 | _socialQueue.push({ 2 | url: '//platform.linkedin.com/in.js', 3 | id: 'name; ?>', 4 | onload: function(f) { 5 | 6 | // Google Analytics tracking 7 | // @todo check if Linked in callbacks are working & update this 8 | var trackerName = _ga.buildTrackerName_(); 9 | _ga.trackLinkedIn = { 10 | // LinkedIn callbacks seem broken, I've included these anyway... 11 | success: function() { 12 | _gaq.push([trackerName + '_trackSocial', 'linkedin', 'share', targetUrl, opt_pageUrl]); 13 | }, 14 | error: function() { 15 | _gaq.push([trackerName + '_trackSocial', 'linkedin', 'error', targetUrl, opt_pageUrl]); 16 | } 17 | }; 18 | // If jQuery is present, bind a click event to the linked in anchor and let Google know about any clicks we capture 19 | if (typeof jQuery !== 'undefined') { 20 | $('.IN-widget').click(function(){ 21 | _gaq.push([trackerName + '_trackSocial', 'linkedin', 'click', $(this).parents('div.coi-social-button-linkedIn').find('script').data('url')]); 22 | }); 23 | } 24 | 25 | // Fade button in if desired 26 | if ('fadeIn ?>') { 27 | f.awaitRender({ 28 | buttons: document.getElementsByClassName('coi-social-button-name; ?>'), 29 | duration: 'fadeIn; ?>', 30 | isRendered: function(element) { 31 | return element.getElementsByClassName('IN-widget').length; 32 | } 33 | }); 34 | } 35 | } 36 | }); 37 | -------------------------------------------------------------------------------- /templates/twitter/script.js: -------------------------------------------------------------------------------- 1 | _socialQueue.push({ 2 | url: 'http://platform.twitter.com/widgets.js', 3 | id: 'name; ?>', 4 | onload: function(f) { 5 | 6 | // Google Analytics tracking 7 | 8 | /** 9 | * Tracks everytime a user clicks on a tweet button from Twitter. 10 | * This subscribes to the Twitter JS API event mechanism to listen for 11 | * clicks coming from this page. Details here: 12 | * http://dev.twitter.com/pages/intents-events#click 13 | * This method should be called once the twitter API has loaded. 14 | * @param {string} opt_pageUrl An optional URL to associate the social 15 | * tracking with a particular page. 16 | * @param {string} opt_trackerName An optional name for the tracker object. 17 | */ 18 | _ga.trackTwitter = function(opt_pageUrl, opt_trackerName) { 19 | var trackerName = _ga.buildTrackerName_(opt_trackerName); 20 | try { 21 | if (twttr && twttr.events && twttr.events.bind) { 22 | twttr.events.bind('tweet', function(event) { 23 | if (event) { 24 | var targetUrl; // Default value is undefined. 25 | if (event.target && event.target.nodeName == 'IFRAME') { 26 | targetUrl = _ga.extractParamFromUri_(event.target.src, 'url'); 27 | } 28 | _gaq.push([trackerName + '_trackSocial', 'twitter', 'tweet', targetUrl, opt_pageUrl]); 29 | } 30 | }); 31 | } 32 | } catch (e) {} 33 | }; 34 | 35 | _ga.trackTwitter(); 36 | 37 | // Fade button in if desired 38 | if ('fadeIn; ?>') { 39 | var body = document.getElementsByTagName('body')[0]; 40 | var twitterFadeInterval = window.setInterval(function() { 41 | if (body.getAttribute('data-twttr-rendered')) { 42 | f.fadeIn(document.getElementsByClassName('coi-social-button-name; ?>'), 'fadeIn; ?>'); 43 | window.clearInterval(twitterFadeInterval); 44 | } 45 | }, 100); 46 | } 47 | } 48 | }); 49 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PHP Socializer 2 | ---------- 3 | 4 | PHP module intended to make adding social sharing buttons more enjoyable. 5 | Includes Google Analytics hooks to enable tracking of share activity. 6 | 7 | Currently supports Twitter, Facebook, Google Plus, LinkedIn, StumbleUpon, GitHub and Flattr buttons. 8 | 9 | Basic Example 10 | ------------- 11 | 12 | ![PHP Socializer Basic Example](http://pagesofinterest.net/images/github/coi-social/basic.png "PHP Socializer Basic Example") 13 | 14 | These buttons can be created with the following code: 15 | 16 | ```php 17 | new Social\Twitter(array( 28 | 'username' => 'pagesofinterest', 29 | )), 30 | 'googleplus' => new Social\GooglePlus(array( 31 | 'size' => 'medium' 32 | )), 33 | 'linkedIn' => new Social\LinkedIn() 34 | ), array( 35 | 'fadeIn' => 400 36 | )); 37 | 38 | /* Where the buttons should be displayed */ 39 | echo $socialManager->render(array( 40 | // These options override those used in the manager initialisation above 41 | 'url' => 'http://pagesofinterest.net/', 42 | 'title' => 'Pages of Interest', 43 | )); 44 | 45 | /* In your footer, just above the closing tag */ 46 | // Output the "; 69 | } 70 | } 71 | 72 | -------------------------------------------------------------------------------- /classes/COI/Social/AbstractElement.php: -------------------------------------------------------------------------------- 1 | value options to use with this element 19 | */ 20 | public function __construct(array $options = array()) { 21 | // Set the name of this button 22 | $this->name = strtolower(substr(get_called_class(), strrpos(get_called_class(), '\\')+1)); 23 | 24 | // Most buttons take a url, add it for convenience 25 | $options = array_merge(array( 26 | 'url' => getCurrentUrl() 27 | ), $options); 28 | foreach ($options as $name => $value) { 29 | $this->$name = $value; 30 | } 31 | $this->templateDir = __DIR__.'/../../../templates/'.strtolower(getClassName($this)); 32 | } 33 | 34 | public function getView() { 35 | return 'html'; 36 | } 37 | 38 | public function render(array $options = array()) { 39 | $this->wasOutput = true; 40 | 41 | $options = array_merge(get_object_vars($this), $options); 42 | $fadeIn = isset($options['fadeIn']) && $options['fadeIn'] ? 'style="opacity:0;"' : ''; 43 | 44 | $html = $this->template($this->getView(), 'buttons', $options); 45 | return "
{$html}
"; 46 | } 47 | 48 | public function script() { 49 | return $this->template('script', null, array_merge(get_object_vars($this)), 'js'); 50 | } 51 | 52 | private function template($templateName, $subDir = null, $parameters = array(), $extension = 'php') { 53 | if (!is_file($this->templateDir."/{$subDir}/{$templateName}.{$extension}")) { 54 | return ''; 55 | } 56 | extract($parameters); 57 | ob_start(); 58 | include $this->templateDir."/{$subDir}/{$templateName}.{$extension}"; 59 | return ob_get_clean(); 60 | } 61 | 62 | public function wasOutput() { 63 | return $this->wasOutput; 64 | } 65 | 66 | public function __toString() { 67 | $html = $this->render(); 68 | $js = $this->script(); 69 | if ($js) { 70 | $html .= ""; 71 | } 72 | return $html; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /classes/COI/Social/Compressor.php: -------------------------------------------------------------------------------- 1 | js = $js; 28 | $this->compression = $compression; 29 | } 30 | 31 | /** 32 | * Make the appropriate compression method call. 33 | * 34 | * @return String The compressed javascript 35 | * @throws Exception If $this->compression is set to an unrecognised compressor 36 | */ 37 | public function compress() { 38 | switch ($this->compression) { 39 | case Compressor\BOOSTER: { 40 | return $this->booster(); 41 | } 42 | case Compressor\PACKER: { 43 | return $this->packer(); 44 | } 45 | case Compressor\JSHRINK: { 46 | return $this->jshrink(); 47 | } 48 | default: { 49 | throw new Exception("Unrecognized compression method: {$this->compression}"); 50 | } 51 | } 52 | } 53 | 54 | /** 55 | * Compress using the {@link https://github.com/Schepp/CSS-JS-Booster CSS-JS-Booster} compression library. 56 | * 57 | * @return String The compressed JavaScript 58 | * @throws Exception If the CSS-JS-Booster library could not be found 59 | */ 60 | public function booster() { 61 | // Flush any output in the buffer - prevents Content Encoding Errors {@link http://stackoverflow.com/a/11007081/187954} 62 | ob_flush(); 63 | $boosterPath = __DIR__.'/../../../dependencies/CSS-JS-Booster/booster/booster_inc.php'; 64 | if (!is_file($boosterPath)) { 65 | throw new Exception("Failed to load Booster at {$boosterPath}"); 66 | } 67 | include_once $boosterPath; 68 | $booster = new Booster(); 69 | $booster->js_stringmode = TRUE; 70 | $booster->js_source = $this->js; 71 | return $booster->js(); 72 | } 73 | 74 | /** 75 | * Compress using the {@link http://joliclic.free.fr/php/javascript-packer/en/ Packer} compression library. 76 | * 77 | * @return String The compressed JavaScript 78 | * @throws Exception If the Packer library could not be found 79 | */ 80 | public function packer() { 81 | $packerPath = __DIR__.'/../../../dependencies/Packer/class.JavaScriptPacker.php'; 82 | if (!is_file($packerPath)) { 83 | throw new Exception("Failed to load Packer at {$packerPath}"); 84 | } 85 | include_once $packerPath; 86 | $packer = new JavaScriptPacker($this->js); 87 | 88 | return $packer->pack(); 89 | } 90 | 91 | /** 92 | * Compress using the {@link https://github.com/tedivm/JShrink/ JShrink} compression library. 93 | * 94 | * @return String The compressed JavaScript 95 | * @throws Exception If the JShrink library could not be found 96 | */ 97 | public function jshrink() { 98 | $jshrinkPath = __DIR__.'/../../../dependencies/JShrink/src/JShrink/Minifier.php'; 99 | if (!is_file($jshrinkPath)) { 100 | throw new Exception("Failed to load JShrink at {$jshrinkPath}"); 101 | } 102 | include_once $jshrinkPath; 103 | return JShrink\Minifier::minify($this->js, array('flaggedComments' => false)); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /classes/COI/Social/Manager.php: -------------------------------------------------------------------------------- 1 | elements = $elements; 24 | foreach($this->elements as $element) { 25 | foreach($commonOptions as $name => $value) { 26 | $element->$name = $value; 27 | } 28 | } 29 | // Add this instance to the shared collection 30 | self::$managers[] = $this; 31 | } 32 | 33 | /** 34 | * Return the HTML for configured buttons 35 | * @param array $options Overrides for preconfigured options 36 | * @param array $exclude Names of buttons to be excluded 37 | * @return String the button's HTML 38 | */ 39 | public function render($options = array(), $exclude = array()) { 40 | $html = ''; 41 | foreach ($this->elements as $name => $element) { 42 | if (!$exclude || !in_array($name, $exclude)) { 43 | $html .= $element->render($options); 44 | } 45 | } 46 | return $html; 47 | } 48 | 49 | /** 50 | * 51 | * @return String JavaScript common to all social elements 52 | */ 53 | private static function commonJS() { 54 | if (self::$outputScripts) { 55 | return null; 56 | } 57 | ob_start(); 58 | include __DIR__.'/../../../templates/script.js'; 59 | return ob_get_clean(); 60 | } 61 | 62 | /** 63 | * Prepare and return JavaScript required for this instance's social elements 64 | * @param Array $options Optional array of JavaScript options 65 | * @return String 66 | */ 67 | public function javaScript($options = array()) { 68 | $js[] = self::commonJS(); 69 | 70 | foreach ($this->elements as $element) { 71 | if (!isset(self::$outputScripts[get_class($element)])) { 72 | $js[] = $element->script(); 73 | self::$outputScripts[get_class($element)] = true; 74 | } 75 | } 76 | $js = implode('', $js); 77 | 78 | if (self::$combining) { 79 | return $js; 80 | } 81 | 82 | return self::cache(self::compress($js, $options), $options); 83 | } 84 | 85 | public static function combinedJavaScript($options = array()) { 86 | 87 | self::$combining = true; 88 | 89 | $js = ''; 90 | 91 | foreach (self::$managers as $manager) { 92 | $js .= $manager->javaScript($options); 93 | } 94 | 95 | self::$combining = false; 96 | return self::cache(self::compress($js, $options), $options); 97 | } 98 | 99 | public static function compress($js, $options) { 100 | if (isset($options['compression']) && $options['compression']) { 101 | $compressor = new Compressor($js, $options['compression']); 102 | $js = $compressor->compress(); 103 | } 104 | return $js; 105 | } 106 | 107 | public static function cache($js, $options) { 108 | if (isset($options['cacheDirectory']) && $options['cacheDirectory']) { 109 | $cache = new Cache($js, $options['cacheDirectory'], $options); 110 | return $cache->output(); 111 | } else { 112 | return ''; 113 | } 114 | } 115 | 116 | public function __set($name, $value) { 117 | $this->elements[$name] = $value; 118 | } 119 | 120 | public function __get($name){ 121 | if (array_key_exists($name, $this->elements)) { 122 | return $this->elements[$name]; 123 | } 124 | 125 | $trace = debug_backtrace(); 126 | trigger_error( 127 | 'Undefined property via __get(): ' . $name . 128 | ' in ' . $trace[0]['file'] . 129 | ' on line ' . $trace[0]['line'], 130 | E_USER_NOTICE); 131 | return null; 132 | } 133 | 134 | public function buttonsOutput() { 135 | 136 | foreach ($this->elements as $element) { 137 | if ($element->wasOutput()) return true; 138 | } 139 | 140 | return false; 141 | } 142 | 143 | } 144 | -------------------------------------------------------------------------------- /public/github/button.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/script.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @fileoverview Core PHP Social functions 3 | * @author Michael Robinson 4 | */ 5 | 6 | /** 7 | * Following section taken from Google's social media tracking documentation 8 | * A simple script to automatically track Facebook and Twitter 9 | * buttons using Google Analytics social tracking feature. 10 | * 11 | * @author api.nickm@google.com (Nick Mihailovski) 12 | * Copyright 2011 Google Inc. All Rights Reserved. 13 | */ 14 | 15 | /** 16 | * Namespace. 17 | * @type {Object}. 18 | */ 19 | var _ga = _ga || {}; 20 | 21 | /** 22 | * Ensure global _gaq Google Analytics queue has been initialized. 23 | * @type {Array} 24 | */ 25 | var _gaq = _gaq || []; 26 | 27 | /** 28 | * Returns the normalized tracker name configuration parameter. 29 | * @param {string} opt_trackerName An optional name for the tracker object. 30 | * @return {string} If opt_trackerName is set, then the value appended with 31 | * a . Otherwise an empty string. 32 | * @private 33 | */ 34 | _ga.buildTrackerName_ = function(opt_trackerName) { 35 | return opt_trackerName ? opt_trackerName + '.' : ''; 36 | }; 37 | 38 | /** 39 | * Extracts a query parameter value from a URI. 40 | * @param {string} uri The URI from which to extract the parameter. 41 | * @param {string} paramName The name of the query paramater to extract. 42 | * @return {string} The un-encoded value of the query paramater. underfined 43 | * if there is no URI parameter. 44 | * @private 45 | */ 46 | _ga.extractParamFromUri_ = function(uri, paramName) { 47 | if (!uri) { 48 | return; 49 | } 50 | uri = uri.split('#')[0]; // Remove anchor. 51 | var parts = uri.split('?'); // Check for query params. 52 | if (parts.length == 1) { 53 | return; 54 | } 55 | var query = decodeURI(parts[1]); 56 | 57 | // Find url param. 58 | paramName += '='; 59 | var params = query.split('&'); 60 | for (var i = 0, param; param = params[i]; ++i) { 61 | if (param.indexOf(paramName) === 0) { 62 | return unescape(param.split('=')[1]); 63 | } 64 | } 65 | return; 66 | }; 67 | 68 | /** 69 | * PHP Socializer functions 70 | */ 71 | 72 | /** 73 | * @type {mixed[]} List of social objects to be loaded when the document is ready 74 | */ 75 | _socialQueue = []; 76 | 77 | /** 78 | * @param {Object} w The window. 79 | * @param {Object} d The document. 80 | */ 81 | (function(w, d) { 82 | 83 | /** 84 | * Begin loading social assets. 85 | */ 86 | var go = function() { 87 | 88 | /** @type {Object} Fade handling object. */ 89 | var f = { 90 | 91 | /** 92 | * Simple fade in effect. 93 | * 94 | * @param {Array} elements An array of elements to fade in 95 | * @param {Integer} time Total animation time 96 | */ 97 | fadeIn: function(elements, time) { 98 | // If the browser supports CSS transitions, use them 99 | var transition = false, 100 | transitionNames = ['MozTransition', 'webkitTransition', 'OTransition']; 101 | for (var i = 0; i < transitionNames.length; i++) { 102 | if (typeof elements[0].style[transitionNames[i]] !== 'undefined') { 103 | transition = transitionNames[i]; 104 | break; 105 | } 106 | } 107 | 108 | for (i = 0; i < elements.length; i++) { 109 | if (transition) { 110 | elements[i].style[transition] = 'opacity ' + time + 'ms ease-in ' + time + 'ms'; 111 | elements[i].style.opacity = 1; 112 | } else { 113 | var startOpacity = 0, steps = 1 / 0.02; 114 | (function step(element) { 115 | element.style.opacity = +(element.style.opacity) + 0.02; 116 | 117 | // for IE 118 | element.style.filter = 'alpha(opacity=' + element.style.opacity * 100 + ')'; 119 | 120 | if(element.style.opacity < 1) { 121 | window.setTimeout(function() { step(element); }, time / steps); 122 | } 123 | })(elements[i]); 124 | } 125 | } 126 | }, 127 | /** 128 | * Attach the f.fadeIn function as an onload event to the iFrame, 129 | * then 'kick' it. 130 | * 131 | * @param {Element} fr The iFrame 132 | * @param {Element} b The wrapping div. 133 | * @param {int} d Fade animation duration. 134 | */ 135 | iframeOnload: function(fr, b, d) { 136 | fr.onload = function() { 137 | f.fadeIn([b], d); 138 | }; 139 | var src = fr.src; 140 | fr.src = ''; 141 | fr.src = src; 142 | }, 143 | 144 | /** 145 | * Repeatedly check if button is rendered, when it is, perform 146 | * appropriate action. 147 | * 148 | * @param {Element} b The wrapping div. 149 | * @param {Function} r Function to call with b, returns true or false 150 | * depending on whether button is rendered. 151 | * @param {int} d Fade animation duration. 152 | * @param {Function} m Optional function to be called when rendered. 153 | */ 154 | awaitRenderButton: function(b, r, d, m) { 155 | if (!r(b)) { // Button not rendered yet, wait 156 | window.setTimeout(function() { 157 | f.awaitRenderButton(b, r, d, m); 158 | }, 100); 159 | return; 160 | } 161 | // Button rendered 162 | if (typeof m !== 'undefined') { // An alternative rendered function was provided 163 | m(b, d); 164 | } else { // Fade in 165 | f.fadeIn([b], d); 166 | } 167 | }, 168 | 169 | /** 170 | * Entry point to the fade in handling object. 171 | * 172 | * @param {Object} o Hash of options. 173 | */ 174 | awaitRender: function(o) { 175 | for(var i = 0; i < o.buttons.length; i++) { 176 | f.awaitRenderButton(o.buttons[i], o.isRendered, o.duration, o.renderedMethod); 177 | } 178 | } 179 | }; 180 | 181 | var fjs = document.getElementsByTagName('script')[0]; 182 | 183 | /** 184 | * Load the social object 185 | * @param {Object} s A social object to be loaded 186 | */ 187 | var load = function(s, f) { 188 | // Ensure script isn't loaded yet 189 | if (d.getElementById(s.id)) { 190 | return; 191 | } 192 | 193 | if (s.preload) { 194 | s.preload(f); 195 | } 196 | 197 | if (s.url) { 198 | 199 | // Create and initialise script 200 | var js = d.createElement('script'); 201 | js.src = s.url; 202 | js.id = '_social' + s.id; 203 | js.async = true; 204 | 205 | if (s.onload) { // Attach the onload function if present 206 | js.onload = function() { s.onload(f); }; 207 | } 208 | 209 | fjs.parentNode.insertBefore(js, fjs); 210 | } 211 | }; 212 | 213 | // Process queue 214 | for (var i = 0; i < _socialQueue.length; i++) { 215 | load(_socialQueue[i], f); 216 | } 217 | }; 218 | 219 | // Bind 'go' function to load event 220 | if (w.addEventListener) { 221 | w.addEventListener('load', go, false); 222 | } else if (w.attachEvent) { 223 | w.attachEvent('onload', go); 224 | } 225 | 226 | })(window, document); 227 | --------------------------------------------------------------------------------