Created
December 7, 2011 05:38
-
-
Save msng/1441605 to your computer and use it in GitHub Desktop.
OGP Helper class file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Ogp Helper class file | |
* | |
* Adds OGP elements in <head /> | |
* | |
* Licensed under The MIT License | |
* | |
* @author Masunaga Ray (http://www.msng.info/) | |
* @link http://www.msng.info/archives/2011/12/cakephp-ogp-helper.php | |
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
*/ | |
class OgpHelper extends AppHelper | |
{ | |
public $helpers = array('Html'); | |
/** | |
* Decides whether or not each property should be taken automatically | |
* | |
* Works only when the property is not configured anywhere. | |
**/ | |
public $autoGetUrl = true; | |
public $autoGetTitle = true; | |
public $autoGetSiteName = true; | |
public $autoGetLocale = true; | |
/** | |
* Names for configurations | |
**/ | |
public $configName = 'OGP'; | |
public $configLocaleName = 'OGPlocales'; | |
public $varName = 'ogp_params'; | |
/** | |
* Default values for OGP are read from this property, | |
* Configure::read['OGP'] and View variable $ogp_params (by default) | |
* and the former is overwritten by the latter. | |
* Set to false to skip adding the property. | |
**/ | |
public $defaults = array( | |
'fb:admins' => false, | |
'fb:app_id' => false, | |
'og:url' => false, | |
'og:type' => 'website', | |
'og:title' => false, | |
'og:locale' => false, | |
'og:site_name' => false, | |
'og:image' => false, | |
'og:description' => false, | |
); | |
/** | |
* Map for CakePHP's config.language with Facebook's locale code | |
* used by _getLocale method. | |
* | |
* Since they can not be associated one to one, | |
* these values are supposed to be overwritten by Configure::write('OGPlocales'). | |
**/ | |
public $locales = array( | |
'ja' => 'ja_JP', | |
'en' => 'en_US', | |
); | |
/** | |
* Namespace attributes for OGP and Facebook | |
**/ | |
protected $_ns = ' xmlns:og="http://ogp.me/ns#" xmlns:fb="http://www.facebook.com/2008/fbml"'; | |
/** | |
* Map used to correct irregular property names | |
**/ | |
protected $_propertyNames = array( | |
'admin' => 'fb:admins', | |
'admins' => 'fb:admins', | |
'app_id' => 'fb:app_id', | |
'appid' => 'fb:app_id', | |
'appId' => 'fb:app_id', | |
'appID' => 'fb:app_id', | |
'url' => 'og:url', | |
'URL' => 'og:url', | |
'type' => 'og:type', | |
'title' => 'og:title', | |
'locale' => 'og:locale', | |
'site_name' => 'og:site_name', | |
'sitename' => 'og:site_name', | |
'siteName' => 'og:site_name', | |
'image' => 'og:image', | |
'img' => 'og:image', | |
'description' => 'og:description', | |
); | |
protected $_properties = array(); | |
public function __construct() { | |
$this->view =& ClassRegistry::getObject('view'); | |
} | |
/** | |
* Sets default values | |
**/ | |
public function beforeRender() { | |
$this->defaults = $this->_normalize($this->defaults); | |
$conf = $this->_normalize(Configure::read($this->configName)); | |
$viewVar = $this->_normalize($this->view->getVar($this->varName)); | |
$ogp = array_merge($this->defaults, $conf, $viewVar); | |
if ($this->autoGetUrl && empty($ogp['og:url'])) { | |
$ogp['og:url'] = $this->url(null, true); | |
} | |
if ($this->autoGetTitle && empty($ogp['og:title'])) { | |
$ogp['og:title'] = $this->_getTitle(); | |
} | |
if ($this->autoGetSiteName && empty($ogp['og:site_name'])) { | |
$ogp['og:site_name'] = $this->_getSiteName(); | |
} | |
if ($this->autoGetLocale && empty($ogp['og:locale'])) { | |
$ogp['og:locale'] = $this->_getLocale(); | |
} | |
foreach ($ogp as $property => $content) { | |
$this->set($property, $content); | |
} | |
} | |
/** | |
* Sets a meta tag in the view layout's <head /> | |
**/ | |
public function set($property, $content = false, $id = false) { | |
if ($property) { | |
$property = $this->_getPropertyName($property); | |
if (empty($this->_properties[$property]) || !in_array($content, $this->_properties[$property])) { | |
if ($id === false) { | |
if ($property == 'og:image' && isset($this->_properties['og:image'])) { | |
$id = count($this->_properties['og:image']); | |
} else { | |
$id = 0; | |
} | |
} | |
if ($content === false) { | |
return $this->delete($property, $id); | |
} else { | |
$propertyId = $this->_getPropertyId($property, $id); | |
$meta = $this->Html->meta(null, null, array( | |
'property' => $property, | |
'content' => $content, | |
'inline' => true, | |
)); | |
$this->view->addScript($propertyId, $meta); | |
$this->_properties[$property][$id] = $meta; | |
} | |
} | |
} | |
return $content; | |
} | |
/** | |
* Deletes a tag associated with property name and the ID. | |
**/ | |
public function delete($property, $id = 0) { | |
if ($property) { | |
$property = $this->_getPropertyName($property); | |
$propertyId = $this->_getPropertyId($property, $id); | |
if (isset($this->view->__scripts[$propertyId], $this->_properties[$property][$id])) { | |
unset($this->view->__scripts[$propertyId]); | |
unset($this->_properties[$property][$id]); | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Returns namespace attributes for OGP and Facebook. | |
**/ | |
public function ns() { | |
return $this->_ns; | |
} | |
/** | |
* Normalizes property names set as keys of an array | |
**/ | |
protected function _normalize($ogp) { | |
if (is_array($ogp)) { | |
foreach ($ogp as $property => $content) { | |
$propertyName = $this->_getPropertyName($property); | |
if ($propertyName != $property) { | |
unset($ogp[$property]); | |
$ogp[$propertyName] = $content; | |
} | |
} | |
} else { | |
$ogp = array(); | |
} | |
return $ogp; | |
} | |
/** | |
* Returns a proper property name for an OGP tag | |
**/ | |
protected function _getPropertyName($property) { | |
if (isset($this->_propertyNames[$property])) { | |
$property = $this->_propertyNames[$property]; | |
} | |
return $property; | |
} | |
/** | |
* Returns the $title_for_layout for the current view | |
**/ | |
protected function _getTitle() { | |
if (!$title = $this->view->getVar('title_for_layout')) { | |
$title = Inflector::humanize($this->view->viewPath); | |
} | |
if ($title) { | |
return __($title, true); | |
} else { | |
return false; | |
} | |
} | |
/** | |
* Returns the <title /> in the layout | |
**/ | |
protected function _getSiteName() { | |
$layoutFileName = $this->view->_getLayoutFileName(); | |
if ($layoutFileName && file_exists($layoutFileName)) { | |
if ($layout = file_get_contents($layoutFileName)) { | |
$layout = str_replace(array("\r", "\n"), ' ', $layout); | |
$pattern = '#<title.*?>(.+?)</title.*?>#i'; | |
preg_match($pattern, $layout, $matches); | |
$title = $matches[1]; | |
$pattern = '/<\?(?:php|=)(.*?)\?>/i'; | |
preg_match_all($pattern, $title, $codes); | |
if (is_array($codes[1]) && $codes[1]) { | |
$debug = Configure::read('debug'); | |
Configure::write('debug', 0); | |
foreach ($codes[1] as $key => $code) { | |
ob_start(); | |
eval($code); | |
$result = ob_get_contents(); | |
ob_end_clean(); | |
$title = str_replace($codes[0][$key], $result, $title); | |
} | |
Configure::write('debug', $debug); | |
} | |
$title = trim($title); | |
if ($title) { | |
return $title; | |
} | |
} | |
} | |
return false; | |
} | |
/** | |
* Returns a Facebook locale code associated with Config.language | |
**/ | |
protected function _getLocale() { | |
if (!class_exists('L10n')) { | |
App::import('Core', 'l10n'); | |
} | |
$l10n = new L10n; | |
$l10n->get(); | |
$language = Configure::read('Config.language'); | |
if (!empty($_SESSION['Config']['language'])) { | |
$language = $_SESSION['Config']['language']; | |
} | |
if ($language) { | |
$this->locales = array_merge($this->locales, (array)Configure::read($this->configLocaleName)); | |
if (!empty($this->locales[$language])) { | |
return $this->locales[$language]; | |
} | |
} | |
return false; | |
} | |
/** | |
* Creates a property ID string | |
**/ | |
protected function _getPropertyId($property, $id) { | |
return $property . '-' . $id; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment