Skip to content
Snippets Groups Projects
Commit eb2ee268 authored by lucha's avatar lucha Committed by lechuck
Browse files

Flattr plugin version 1.2.0

parent 74359033
Branches
Tags
No related merge requests found
Showing
with 1015 additions and 2243 deletions
<?php
$languages['sq_AL'] = 'Albanian';
$languages['ar_DZ'] = 'Arabic';
$languages['be_BY'] = 'Belarusian';
$languages['bg_BG'] = 'Bulgarian';
$languages['ca_ES'] = 'Catalan';
$languages['zh_CN'] = 'Chinese';
$languages['hr_HR'] = 'Croatian';
$languages['cs_CZ'] = 'Czech';
$languages['da_DK'] = 'Danish';
$languages['nl_NL'] = 'Dutch';
$languages['en_GB'] = 'English';
$languages['et_EE'] = 'Estonian';
$languages['fi_FI'] = 'Finnish';
$languages['fr_FR'] = 'French';
$languages['de_DE'] = 'German';
$languages['el_GR'] = 'Greek';
$languages['iw_IL'] = 'Hebrew';
$languages['hi_IN'] = 'Hindi';
$languages['hu_HU'] = 'Hungarian';
$languages['is_IS'] = 'Icelandic';
$languages['in_ID'] = 'Indonesian';
$languages['ga_IE'] = 'Irish';
$languages['it_IT'] = 'Italian';
$languages['ja_JP'] = 'Japanese';
$languages['ko_KR'] = 'Korean';
$languages['lv_LV'] = 'Latvian';
$languages['lt_LT'] = 'Lithuanian';
$languages['mk_MK'] = 'Macedonian';
$languages['ms_MY'] = 'Malay';
$languages['mt_MT'] = 'Maltese';
$languages['no_NO'] = 'Norwegian';
$languages['pl_PL'] = 'Polish';
$languages['pt_PT'] = 'Portuguese';
$languages['ro_RO'] = 'Romanian';
$languages['ru_RU'] = 'Russian';
$languages['sr_RS'] = 'Serbian';
$languages['sk_SK'] = 'Slovak';
$languages['sl_SI'] = 'Slovenian';
$languages['es_ES'] = 'Spanish';
$languages['sv_SE'] = 'Swedish';
$languages['th_TH'] = 'Thai';
$languages['tr_TR'] = 'Turkish';
$languages['uk_UA'] = 'Ukrainian';
$languages['vi_VN'] = 'Vietnamese';
\ No newline at end of file
<?php
class HttpConnection {
// @param string $base url to the service, i.e http://example.com:80
protected $baseUrl;
// @param array $defaultOptions variable to hold default cURL options.
protected $defaultOptions;
/**
* constructor with some defaults
* @param string $baseUrl
*/
public function __construct($baseUrl = '', $params = array())
{
$this->baseUrl = $baseUrl;
$params = array_merge(array('headers' => array(),'basic_auth' => array()),$params);
if ( ! in_array('Expect:', $params['headers']))
{
$params['headers'][] = 'Expect:'; // lighty needs this
}
$this->defaultOptions = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $params['headers'],
CURLOPT_HEADER => 0,
CURLOPT_USERAGENT => 'curl',
);
if (!empty($params['verify_peer']) && $params['verify_peer'] === false) {
$this->verifyPeer($params['verify_peer']);
}
if ( !empty($params['basic_auth'])) {
$this->setBasicAuth($params['basic_auth']['user'],$params['basic_auth']['password']);
}
}
public function setBasicAuth($user,$password)
{
$this->defaultOptions[CURLOPT_USERPWD] = $user.':'.$password;
}
public function verifyPeer( $verify = true )
{
$this->defaultOptions[CURLOPT_SSL_VERIFYPEER] = $verify;
$this->defaultOptions[CURLOPT_SSL_VERIFYHOST] = $verify;
}
/**
* @param string $resourceUrl
* @param array $headers (optional)
* @return boolean
*/
public function get($resourceUrl, $opts = array())
{
$opts = $this->parseOptions($opts);
if (!empty($opts['params']))
{
$resourceUrl .= (strpos($responseUrl,'?') === false) ? '?' .$opts['params'] : '&'.$opts['params'];
}
$response = new HttpResponse();
$ch = curl_init();
$h = $this->mergeHeaders($opts['headers']);
$merged_curlOptions = array(
CURLOPT_URL => $this->baseUrl.$resourceUrl,
CURLOPT_HTTPHEADER => $h,
CURLOPT_HEADERFUNCTION => array(&$response,'readHeader')
);
// can't use array_merge or the $array + $array since headers is nested array
$curlOptions = $this->defaultOptions;
foreach($merged_curlOptions as $k => $v) {
$curlOptions[$k] = $v;
}
curl_setopt_array($ch,$curlOptions);
$response->body = curl_exec($ch);
$response->errors = curl_error($ch);
$response->info = curl_getinfo($ch);
curl_close($ch);
return $response;
}
/**
* @param string $resourceUrl
* @param mixed $post_body array or string.
* @param array $headers (optional)
* @return boolean
*/
public function post($resourceUrl, $opts= array())
{
$opts = $this->parseOptions($opts);
$response = new HttpResponse();
$ch = curl_init();
$h = $this->mergeHeaders($opts['headers']);
$merged_curlOptions = array(
CURLOPT_URL => $this->baseUrl.$resourceUrl,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $opts['params'],
CURLOPT_HTTPHEADER => $h,
CURLOPT_HEADERFUNCTION => array(&$response,'readHeader')
);
// can't use array_merge or the $array + $array since headers is nested array
$curlOptions = $this->defaultOptions;
foreach($merged_curlOptions as $k => $v) {
$curlOptions[$k] = $v;
}
curl_setopt_array($ch,$curlOptions);
$response->body = curl_exec($ch);
$response->errors = curl_error($ch);
$response->info = curl_getinfo($ch);
curl_close($ch);
return $response;
}
/**
* merge headers with the defaults from curl
* @param array $headers
* @return array $currentHeaders
*/
protected function mergeHeaders( $headers = array() )
{
$currentHeaders = $this->defaultOptions[CURLOPT_HTTPHEADER];
foreach ($headers as $k => $h) {
$header = $k . ': ' . $h;
if ($this->shouldAddRequestHeader($header, $currentHeaders)) {
$currentHeaders[] = $header;
}
}
return $currentHeaders;
}
public function shouldAddRequestHeader($header, &$currentHeaders)
{
if (!in_array($header, $currentHeaders)) {
return true;
} else {
return false;
}
}
protected function parseOptions($options) {
$options = array_merge(array('params' => '', 'headers' => array()), $options);
if ( is_array($options['params']) )
{
$options['params'] = http_build_query($options['params']);
}
return $options;
}
}
<?php
class HttpResponse
{
public $body, $responseCode = null;
public $errors = array();
public $info = array();
public $responseHeaders = array();
public function __construct()
{
}
public function readHeader($ch, $header)
{
list($key, $value) = self::parseHeader($header);
if(empty($value)) {
return strlen($header);
}
if ($key == 0 && strpos($value,'HTTP/1.1 ') === 0) {
$key = 'Status';
$value = str_replace('HTTP/1.1 ','',$value);
$this->responseCode = (int)substr($value,0,3); // cache the response code
}
$this->responseHeaders[$key] = $value;
// !important, return bytes read, curl will fail otherwise
return strlen($header);
}
public static function parseHeader( $header = '' )
{
$exploded = explode(':', $header);
$r = (count($exploded) > 1) ? array() : array(0);
foreach($exploded as $e) {
$r[] = trim($e);
}
return $r;
}
}
<?php
class OAuth2Client
{
protected $settings = array();
protected $http = null;
/**
* creates the oauth2client object with some defaults
*
* @param array $settings overrides default settings.
* @return OAuth2Client
*/
public function __construct( $settings = array() )
{
$this->settings = array_merge(array(
'client_id' => null,
'client_secret' => null,
'base_url' => null,
'site_url' => null,
'authorize_url' => null,
'access_token_url' => null,
'scopes' => null,
'token_param_name' => 'Bearer',
'redirect_uri' => null,
'response_type' => 'code',
'grant_type' => 'authorization_code',
'access_token' => null,
'refresh_token' => null,
'developer_mode' => false,
'format' => 'application/json',
), $settings);
$this->http = new HttpConnection();
if ($this->settings['developer_mode']) {
$this->http->verifyPeer( false );
}
}
/**
* assemble the authorize_url link
*
* @return string authorize url endpoint
*/
public function authorizeUrl()
{
return $this->settings['authorize_url'].'?'.
'client_id='.$this->settings['client_id'].'&'.
'response_type='.$this->settings['response_type'].'&'.
'redirect_uri='.$this->settings['redirect_uri'].'&'.
'scope='.$this->settings['scopes'];
}
/**
* exchange $code for an access_token
*
* @param string $code
* @throws exception
* @return mixed string or false
*/
public function fetchAccessToken($code, $authInParams = false)
{
$params = array(
'code' => $code,
'grant_type' => $this->settings['grant_type'],
);
// @todo if more params is needed, make a loop...
if (!empty($this->settings['redirect_uri'])) {
$params['redirect_uri'] = $this->settings['redirect_uri'];
}
$headers = $this->headers();
if ( $authInParams) {
$headers = $this->headers(false);
$params['client_id'] = $this->settings['client_id'];
$params['client_secret'] = $this->settings['client_secret'];
}
$this->logRequest('POST '.$this->settings['access_token_url'],array(
'params' => $params,
'headers' => $headers,
));
$response = $this->http->post( $this->settings['access_token_url'],
array(
'params' => $params,
'headers' => $headers,
)
);
$this->logResponse($response);
if (!empty($response->body)) {
$prms = self::parseResponse($response);
if(!empty($prms["error"])) {
throw new Exception("Authentication error: " . $prms["error"]);
}
if ( strpos($response->info['http_code'], '20') !== 0 )
{
throw new Exception('failed to create access_token');
}
if ( !empty($prms['token_type']) ) {
$this->settings['token_type'] = $prms['token_type'];
}
$this->settings['access_token'] = $prms['access_token'];
return $prms['access_token'];
} else {
throw new Exception('No body received from POST access_token');
}
return false;
}
/**
* perform a GET api call
*
* @param string $path
* @return HttpResponse
*/
public function get($path)
{
$this->logRequest(
'GET '.$this->uriFor($path),
array(
'headers' => $this->headers(),
)
);
$response = $this->http->get(
$this->uriFor($path),
array(
'headers' => $this->headers(),
)
);
$this->logResponse($response);
return $response;
}
/**
* perform a GET api call, wrapped in OAuth2Client::parseResponse
*
* @param string $path
* @return mixed array or string
*/
public function getParsed($path)
{
$response = $this->get($path);
if (!empty($response->body) ) {
return self::parseResponse($response);
} else {
return array(
'error' => 'did not get a body from '.$uri
);
}
}
/**
* perform a POST api call
*
* @param string $path
* @param array $postarray
* @return HttpResponse
*/
public function post($path, $postarray)
{
$this->logRequest(
'POST '.$this->uriFor($path),
array(
'params' => http_build_query($postarray),
'headers' => $this->headers(),
)
);
$response = $this->http->post(
$this->uriFor($path),
array(
'params' => http_build_query($postarray),
'headers' => $this->headers()
)
);
$this->logResponse($response);
return $response;
}
/**
* assemble headers for an API clall,
* adding Accept and potentially Authorization
*
* @param boolean $authorizationHeader
* @return array $headers
*/
protected function headers($authorizationHeader = true)
{
$headers = array(
'Accept' => $this->settings['format'],
);
if ($authorizationHeader) {
if (! empty($this->settings['access_token'])) {
$headers['Authorization'] = $this->settings['token_param_name'] . ' '
. $this->settings['access_token'];
} else if (! empty($this->settings['client_id']) &&
! empty($this->settings['client_secret'])) {
$headers['Authorization'] = 'Basic ' . base64_encode(
$this->settings['client_id'] . ':' . $this->settings['client_secret']
);
}
}
return $headers;
}
/**
* @todo something to parse yaml, xml, m.m ?
* parses a response and returns an array if successfull
*
* @param HttpResponse $response
* @return mixed array or string $response->body
*/
public static function parseResponse($response)
{
$return = array();
if (strpos($response->info['content_type'],'json') !== false) {
$return = json_decode($response->body,true);
} else if (false) {
} else {
}
return $return;
}
/**
* adds the base_url before a resource $path
*
* @param string $path
* @return string
*/
protected function uriFor($path)
{
return $this->settings['base_url'] . $path;
}
/**
* log a response
*
* @param HttpResponse
* @return void
*/
protected function logResponse($response)
{
if ($this->settings['developer_mode'] && function_exists('slog')) {
slog("");
slog("** LOG RESPONSE **");
slog("HEADERS =>");
slog($response->responseHeaders);
slog("BODY =>");
slog($response->body);
}
}
/**
* log a request
*
* @param string $uri
* @param array $params
*/
protected function logRequest( $uri, $params = array())
{
if ($this->settings['developer_mode'] && function_exists('slog')) {
slog("");
slog("** LOG REQUEST **");
slog($uri);
slog($params);
}
}
}
<?php
require_once('oauth.php');
require_once( 'flattr_xml.php' );
class Flattr_Rest
{
public $http_header;
public $url;
public $http_code;
public $http_info;
public $signature_method;
public $consumer;
public $token;
private $apiVersion = '0.5';
private $error;
private $baseUrl = 'https://api.flattr.com';
public function __construct($consumer_key, $consumer_secret, $oauth_token = null, $oauth_token_secret = null)
{
$this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if ( !empty($oauth_token) && ! empty($oauth_token_secret) )
{
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
}
else
{
$this->token = null;
}
}
// Flattr API methods
public function browse($params)
{
$url = $this->actionUrl('/thing/browse');
if ( isset($params['query']) && $params['query'] != '' )
{
$url .= '/query/' . $params['query'];
}
if ( isset($params['tag']) && $params['tag'] != '' )
{
if ( ! is_array($params['tag']) )
{
$params['tag'] = array($params['tag']);
}
$url .= '/tag/' . implode(',', $params['tag']);
}
if ( isset($params['category']) && $params['category'] != '' )
{
if ( ! is_array($params['category']) )
{
$params['category'] = array($params['category']);
}
$url .= '/category/' . implode(',', $params['category']);
}
if ( isset($params['language']) && $params['language'] != '' )
{
if ( ! is_array($params['language']) )
{
$params['language'] = array($params['language']);
}
$url .= '/language/' . implode(',', $params['language']);
}
if ( isset($params['user']) && $params['user'] != '' )
{
if ( ! is_array($params['user']) )
{
$params['user'] = array($params['user']);
}
$url .= '/user/' . implode(',', $params['user']);
}
$result = $this->get($url);
$dom = new DOMDocument();
$dom->loadXml($result);
$thingXml = $dom->getElementsByTagName('thing');
$things = array();
foreach ($thingXml as $thing)
{
$thingdata = Flattr_Xml::toArray($thing);
if ( is_array($thingdata) )
{
$things[] = $thingdata;
}
}
return $things;
}
public function clickThing($id)
{
$result = $this->get($this->actionUrl('/thing/click/id/' . $id));
if ( $this->http_code == 200 )
{
return true;
}
else
{
$this->error = "Click error " . $this->http_code . ', ' . $this->http_info . "<br />";
return false;
}
}
public function error()
{
return $this->error;
}
/**
* Returns an array of Flattr's categories...
*
* @return array
*/
public function getCategories()
{
$result = $this->get($this->actionUrl('/feed/categories'));
$dom = new DOMDocument();
$dom->loadXml($result);
$catXml = $dom->getElementsByTagName('category');
return Flattr_Xml::toArray( $catXml );
}
/**
* Returns an array of clicks made by the authenticated user during the given period.
*
* @param string $period in the format 'YYYYMM'
*/
public function getClicks( $period )
{
$response = $this->get( $this->actionUrl( "/user/clicks/period/{$period}" ) );
if ( $this->http_code == 200 )
{
$dom = new DOMDocument();
$dom->loadXml( $response );
$clicksXml = $dom->getElementsByTagName( 'click' );
return Flattr_Xml::toArray( $clicksXml );
}
return false;
}
public function getSubscriptions()
{
$response = $this->get( $this->actionUrl( "/subscription/list" ) );
if ( $this->http_code == 200 )
{
$dom = new DOMDocument();
$dom->loadXml( $response );
$subsXml = $dom->getElementsByTagName( 'subscription' );
return Flattr_Xml::toArray( $subsXml );
}
return false;
}
/**
* Returns a thing as an array.
* If a thing could not be found false is returned
*
* @param string $id
* @return array|false
*/
public function getThing( $id )
{
$result = $this->get($this->actionUrl('/thing/get/id/' . $id));
if ( $this->http_code == 200 )
{
$dom = new DOMDocument();
$dom->loadXml($result);
$thingXml = $dom->getElementsByTagName('thing');
if ( ( $thingXml = $thingXml->item(0) ) !== null )
{
return Flattr_Xml::toArray( $thingXml );
}
}
return false;
}
public function getThingByUrl($url)
{
$result = $this->get($this->actionUrl('/thing/get/'), array('url' => urlencode($url)));
if ( $this->http_code == 200 )
{
$dom = new DOMDocument();
$dom->loadXml($result);
$thingXml = $dom->getElementsByTagName('thing');
$thing = Flattr_Xml::toArray($thingXml->item(0));
return $thing;
}
else
{
return false;
}
}
public function getThingClicks($thingId)
{
$result = $this->get($this->actionUrl('/thing/clicks/'), array('thing' => $thingId));
$return = array();
if ( $this->http_code == 200 )
{
$dom = new DOMDocument();
$dom->loadXml($result);
$clicks = $dom->getElementsByTagName('clicks')->item(0);
$anon = $clicks->getElementsByTagName('anonymous')->item(0);
$anonymousClicks = $anon->getElementsByTagName('count')->item(0)->nodeValue;
$public = $clicks->getElementsByTagName('public')->item(0);
$publicClicks = $public->getElementsByTagName('count')->item(0)->nodeValue;
$userArray = array();
$publicUsers = $public->getElementsByTagName('users')->item(0);
$nodes = $publicUsers->getElementsByTagName('user');
for ($i=0; $i<$nodes->length; $i++)
{
$userArray[] = Flattr_Xml::toArray($nodes->item($i));
}
return array('public' => $publicClicks, 'anonymous' => $anonymousClicks, 'publicUsers' => $userArray);
}
else
{
return false;
}
}
/**
* Returns an array of things owned by specified user
* if no userid is given the current authenticated user is used.
*
* @param int $userId
*/
public function getThingList($userId = null)
{
$result = $this->get($this->actionUrl('/thing/listbyuser/id/' . $userId));
$dom = new DOMDocument();
$dom->loadXml($result);
$thingXml = $dom->getElementsByTagName('thing');
return Flattr_Xml::toArray( $thingXml );
}
/**
* Returns an array of Flattr's langauges
*
* @return array
*/
public function getLanguages()
{
$result = $this->get($this->actionUrl('/feed/languages'));
$dom = new DOMDocument();
$dom->loadXml($result);
$langXml = $dom->getElementsByTagName('language');
return Flattr_Xml::toArray( $langXml );
}
/**
* Returns info about the specified user.
* If no user is given the currently authenticated user is used.
*
* @param mixed $user string username | int userId | null
* @return array|false
*/
public function getUserInfo($user = null)
{
$result = null;
if ( !$user )
{
$result = $this->get($this->actionUrl('/user/me'));
}
else
{
if ( is_numeric($user) )
{
$result = $this->get($this->actionUrl('/user/get/id/' . $user));
}
else
{
$result = $this->get($this->actionUrl('/user/get/name/' . $user));
}
}
if (class_exists("DOMDocument")) {
$dom = new DOMDocument();
$dom->loadXml($result);
$userXml = $dom->getElementsByTagName('user');
if ( ( $userXml = $userXml->item(0) ) !== null )
{
return Flattr_Xml::toArray( $userXml );
}
}
return false;
}
/**
* Will register a new thing on flattr.com
*
* @param string $url
* @param string $title
* @param string $category
* @param string $description
* @param string $tags
* @param string $language
* @param bool $hidden
* @param bool $temporary
*/
public function submitThing($url, $title, $category, $description, $tags, $language, $hidden = false, $temporary = false)
{
$dom = new DOMDocument('1.0', 'utf-8');
$node = $dom->appendChild( $dom->createElement('thing') );
Flattr_Xml::addElement($node, 'url', $url);
Flattr_Xml::addElement($node, 'title', $title);
Flattr_Xml::addElement($node, 'category', $category);
Flattr_Xml::addElement($node, 'description', $description);
Flattr_Xml::addElement($node, 'language', $language);
Flattr_Xml::addElement($node, 'hidden', $hidden);
Flattr_Xml::addElement($node, 'temporary', $temporary);
if (trim($tags) != "") {
$tagsNode = $node->appendChild( $dom->createElement('tags') );
foreach ( explode(',', $tags) as $tag )
{
Flattr_Xml::addElement($tagsNode, 'tag', trim($tag));
}
}
$result = $this->post($this->actionUrl('/thing/register'), array('data' => $dom->saveXml()));
if (!empty ($result)) {
$dom = new DOMDocument();
$dom->loadXml($result);
$thingXml = $dom->getElementsByTagName('thing');
return Flattr_Xml::toArray( $thingXml->item(0) );
}
return false;
}
// Oauth specific
public function getAccessToken($verifier)
{
$parameters = array('oauth_verifier' => $verifier);
$request = $this->oAuthRequest($this->accessTokenUrl(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
if ( isset($token['oauth_token']) && isset($token['oauth_token_secret']) )
{
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
}
public function getAuthorizeUrl($token, $access = 'read')
{
return $this->authorizeUrl() . '?oauth_token=' . $token['oauth_token'] . '&access_scope=' . $access;
}
/**
* Gets a request token from the API server and returns an oauth token.
*
* @param string $callback a callback url (fully qualified)
* @return array oauth response parameters as array
*/
public function getRequestToken($callback = null)
{
$parameters = array();
if ( !empty($callback) )
{
$parameters['oauth_callback'] = $callback;
}
$response = $this->oAuthRequest($this->requestTokenUrl(), 'GET', $parameters);
$responseParameters = OAuthUtil::parse_parameters($response);
if ( isset($responseParameters['oauth_token']) && isset($responseParameters['oauth_token_secret']) )
{
$this->token = new OAuthConsumer($responseParameters['oauth_token'], $responseParameters['oauth_token_secret']);
}
else
{
$this->error = $responseParameters['oauth_problem'];
}
return $responseParameters;
}
// INTERNAL
private function accessTokenUrl()
{
return $this->baseUrl . '/oauth/access_token';
}
private function actionUrl($uri)
{
return $this->baseUrl . '/rest/' . $this->apiVersion . $uri;
}
private function authorizeUrl()
{
return $this->baseUrl . '/oauth/authorize';
}
private function get($url, $parameters = array())
{
$response = $this->oAuthRequest($url, 'GET', $parameters);
return $response;
}
private function requestTokenUrl()
{
return $this->baseUrl . '/oauth/request_token';
}
private function getHeader($ch, $header)
{
$i = strpos($header, ':');
if (!empty($i))
{
$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
$value = trim(substr($header, $i + 2));
$this->http_header[$key] = $value;
}
return strlen($header);
}
private function http($url, $method, $postfields = array(), $headers = array())
{
$this->http_info = array();
$ci = curl_init();
$headers[] = 'Expect:';
curl_setopt($ci, CURLOPT_USERAGENT, 'Flattrbot/0.1');
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ci, CURLOPT_TIMEOUT, 10);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
curl_setopt($ci, CURLOPT_HEADER, FALSE);
switch ($method)
{
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($postfields))
{
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
break;
case 'DELETE':
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($postfields))
{
$url = "{$url}?{$postfields}";
}
}
curl_setopt($ci, CURLOPT_URL, $url);
$response = curl_exec($ci);
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
$this->url = $url;
curl_close ($ci);
return $response;
}
private function oAuthRequest($url, $method, $parameters, $headers = array())
{
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0)
{
$url = "{$this->host}{$url}.{$this->format}";
}
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
$request->sign_request($this->signature_method, $this->consumer, $this->token);
$headers['Authorization'] = $request->to_header();
switch ($method)
{
case 'GET':
return $this->http($request->to_url(), 'GET', null, $headers);
default:
return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata(), $headers);
}
}
private function post($url, $parameters = array())
{
$response = $this->oAuthRequest($url, 'POST', $parameters);
return $response;
}
}
<?php
class Flattr_Xml
{
public static function addElement(DOMNode $node, $name, $value)
{
if ( is_bool( $value ) )
{
$value = (int)$value;
}
if ( $value instanceOf DOMNode )
{
throw new Exception('Construction blocks your path!');
}
else if ( is_numeric( $value ) )
{
$node->appendChild( new DOMElement($name, $value) );
}
else
{
$elm = $node->appendChild( new DOMElement($name) );
$elm->appendChild( $node->ownerDocument->createCDATASection($value) );
}
}
/**
* Checks if node has any children other than just text
*
* @param DOMNode
* @return boolean
*/
public static function nodeHasChild( $node )
{
if ( $node->hasChildNodes() )
{
foreach ( $node->childNodes as $child )
{
if ( $child->nodeType == XML_ELEMENT_NODE )
{
return true;
}
}
}
return false;
}
/**
* Takes a DOMNode (or a DOMNodeList) and returns it as an array
*
* @param DOMNode|DOMNodeList $item
* @return array
*/
public static function toArray( $xml )
{
if ( $xml instanceOf DOMNodeList )
{
$items = array();
foreach ( $xml as $item )
{
$items[] = self::toArray( $item );
}
return $items;
}
$itemData = array();
foreach ( $xml->childNodes as $node )
{
if ( self::nodeHasChild( $node ) )
{
$itemData[$node->nodeName] = self::toArray( $node );
}
else
{
$itemData[$node->nodeName] = $node->nodeValue;
}
}
return $itemData;
}
}
\ No newline at end of file
This diff is collapsed.
<input type="checkbox" value="1" name="flattr_btn_disabled" <?php if ((bool)$btnDisabled) { echo 'checked="checked"'; } ?>/>
Disable the Flattr button on this post?
<input type="checkbox" value="1" name="flattr_btn_disabled" id="flattr_btn_disabled" <?php if ((bool)$btnDisabled) { echo 'checked="checked"'; } ?>/>
<label for="flattr_btn_disabled">Disable the Flattr button on this post?</label>
<br />
<label for="flattr_post_language"><?php echo __('Language:') ?></label>
<select name="flattr_post_language" id="flattr_post_language">
<?php
if (!$selectedLanguage) {
echo '<option value="0" selected>Default</option>';
}
foreach (Flattr::getLanguages() as $languageCode => $language)
{
printf('<option value="%s" %s>%s</option>',
......@@ -21,6 +24,9 @@
<label for="flattr_post_category"><?php echo __('Category:') ?></label>
<select name="flattr_post_category" id="flattr_post_category">
<?php
if (!$selectedLanguage) {
echo '<option value="0" selected>Default</option>';
}
foreach (Flattr::getCategories() as $category)
{
printf('<option value="%s" %s>%s</option>',
......@@ -35,7 +41,9 @@
<br />
<input type="hidden" value="0" name="flattr_post_hidden" />
<input type="checkbox" value="1" name="flattr_post_hidden" <?php if ((bool)$hidden) { echo 'checked="checked"'; } ?>/>
Hide post from listings on flattr.com
<input type="checkbox" value="1" name="flattr_post_hidden" id="flattr_post_hidden" <?php if ((bool)$hidden) { echo 'checked="checked"'; } ?>/>
<label for="flattr_post_hidden">Hide post from listings on flattr.com</label>
<br />
<label for="flattr_post_customurl">Custom URL to be flattred</label>
<input type="text" name="flattr_post_customurl" id="flattr_post_customurl" value="<?php echo $customUrl; ?>" />
......@@ -20,10 +20,21 @@ class Flattr_PostMeta
return $id;
}
if ( isset($_POST['flattr_post_language']) && $_POST['flattr_post_language'] != '0' ) {
add_post_meta($id, '_flattr_post_language', $_POST['flattr_post_language'], true) or update_post_meta($id, '_flattr_post_language', $_POST['flattr_post_language']);
}
if ( isset($_POST['flattr_post_category']) && $_POST['flattr_post_category'] != '0' ) {
add_post_meta($id, '_flattr_post_category', $_POST['flattr_post_category'], true) or update_post_meta($id, '_flattr_post_category', $_POST['flattr_post_category']);
}
if ( isset($_POST['flattr_post_hidden']) ) {
add_post_meta($id, '_flattr_post_hidden', $_POST['flattr_post_hidden'], true) or update_post_meta($id, '_flattr_post_hidden', $_POST['flattr_post_hidden']);
}
if ( isset($_POST['flattr_btn_disabled']) ) {
add_post_meta($id, '_flattr_btn_disabled', $_POST['flattr_btn_disabled'], true) or update_post_meta($id, '_flattr_btn_disabled', $_POST['flattr_btn_disabled']);
}
if ( isset($_POST['flattr_post_customurl']) ) {
add_post_meta($id, '_flattr_post_customurl', $_POST['flattr_post_customurl'], true) or update_post_meta($id, '_flattr_post_customurl', $_POST['flattr_post_customurl']);
}
return true;
}
......@@ -65,13 +76,13 @@ class Flattr_PostMeta
$selectedLanguage = get_post_meta($post->ID, '_flattr_post_language', true);
if (empty($selectedLanguage))
{
$selectedLanguage = get_option('flattr_lng');
$selectedLanguage = false;
}
$selectedCategory = get_post_meta($post->ID, '_flattr_post_category', true);
if (empty($selectedCategory))
{
$selectedCategory = get_option('flattr_cat');
$selectedCategory = false;
}
$hidden = get_post_meta($post->ID, '_flattr_post_hidden', true);
......@@ -86,6 +97,8 @@ class Flattr_PostMeta
$btnDisabled = get_option('flattr_disable', 0);
}
$customUrl = get_post_meta($post->ID, '_flattr_post_customurl', true);
include('postmeta-template.php');
}
......
=== Flattr ===
Contributors: aphex3k
Contributors: aphex3k, VoxPelli
Donate link: https://flattr.com/donation/give/to/der_michael
Tags: flattr, donate, micropayments
Requires at least: 3.0
Tested up to: 3.2
Stable tag: trunk
Requires at least: 3.3
Tested up to: 3.4
Stable tag: 1.2.0
This plugin allows you to easily add a Flattr button to your wordpress blog.
This plugin allows you to easily add a Flattr donation buttons to your blog and blog posts.
== Description ==
......@@ -18,25 +18,99 @@ Flattr solves this issue. When you're registered to flattr, you pay a small mont
== Installation ==
Note that we only support PHP 5 and WordPress 2.9 or above.
To use advanced features like auto-submission or feed-buttons, your web server needs cURL extension installed.
1. Upload the folder 'flattr' to your server in the folder '/wp-content/plugins/'
2. Go to the WordPress control panel and find the 'Plugins' section
3. Activate the plugin 'Flattr'
4. Go to the 'Options' section and authrize your blog against flattr.com
5. Select your default category (which usually would be 'text' if you have a normal blog), select your default language and type in your Flattr user ID (your user ID can be found on your dashboard on http://flattr.com/ )
6. If you want the Flattr button to be automagically included at the end of your posts, leave the checkbox checked
7. If you want to add the Flattr button manually in your theme, uncheck the checkbox and use the following code snippet:
8. When writing or editing a blog post you have the ability to select category and language for this specific blog post.
4. Select your default category (which usually would be 'text' if you have a normal blog), select your default language and type in your Flattr username
5. When writing or editing a blog post you have the ability to select category and language for this specific blog post.
6. Live long and prosper. :)
== Frequently Asked Questions ==
= How do I use the shortcode? =
The shortcode is [flattr url="http://example.com/"]. It has many attributes but the url attribute is the only one required.
Supported attributes are:
* **url** - the URL that should be flattred. *Required*
* **type** - overrides the default setting of the button style to use. Can be either "js", "compact", "text", "image" or "url".
* **popout** - overrides the default setting on whether the popout should be shown. Should be either "yes" or "no".
Additional autosubmit related attributes:
`<?php the_flattr_permalink(); ?>`
* **user** - the username of the user owning the thing - needed for autosubmits.
* **hidden** - overrides the default setting on whether an autosubmit of the thing should be hidden. Should be either "yes" or "no".
* **language** - overrides the blog language as the language of an autosubmit of the thing. Should be a language code like en_GB.
* **category** - overrides the default category for an autosubmit of the thing. Should be one of the [supported ones](http://developers.flattr.net/api/resources/categories/).
* **title** - the title used in an autosubmit of the thing.
* **description** - the description used in an autosubmit of the thing.
* **tags** - a comma separated list of tags that's used in an autosubmit of the thing.
8. Live long and prosper. :)
For options that use "yes" or "no" you can instead of "no" use "n" or "off" - any other value will be interpreted as "yes".
== Upgrade Notice ==
= 1.2.0 =
Flattr buttons now detectable by browsers, site itself can now be flattred, a new shortcode and widgets is available etc.
== Changelog ==
= 1.2.0 =
* New Feature: The payment links in RSS/Atom can now be added without adding the graphical buttons and are now on by default
* New Feature: Payment links are now not only included in feed entries - they are now also by default included in the head-tag of entry pages which is usable for eg. browser extensions to detect the existence of a flattr button.
* New Feature: The site itself can now be become flattrable - both feeds and the frontpage will by default in new installs have a payment links for the site itself. Existing pages needs to activate the "Make frontpage flattrable" option.
* New Feature: Added a widget with a Flattr button for the entire site.
* New Feature: Added a [flattr] shortcode for easy inclusion of Flattr buttons in posts and pages
* New Feature: A post can now specify a custom URL for the Flattr button to flattr instead of the post itself. Thanks for the patch [Erik](http://tapiren.se/2012/02/18/wordpress-flattr-plugin-1-0-1-custom-urls/)!
* New Feature: Made it possible to set a date from which the user specific button setting should be activated
* Fix: User specific buttons can now be activated for all content
* Fix: No longer prevents caching due to needless session initialization
* Fix: Settings that can be overriden by a user setting is now by default not saved in a post but rather the site setting or user setting is instead picked when the button is viewed. This means that user settings for content type and language will now be respected.
* Fix: Users with double encoding troubles of payment metadata in their feeds can now disable the encoding through the settings.
* + more minor fixes and tweaks
= 1.1.1 =
* Added support for the new button popout.
* Replaced getBasePath() with plugin_dir_path()
= 1.1.0 =
* New Feature: Added support for WordPress uninstall feature. To use it you deactivate and delete the plugin from the plugin list.
* Fix: Descriptions sent to Flattr are now assembled in a totaly new way as a custom kind of excerpts that are limited to maximum 30 words
* Fix: The javascript loaded from Flattr.com is now loaded asynchronously
* Fix: The javascript loaded from Flattr.com is now only loaded in the frontend when dynamic buttons are used
= 1.0.2 =
* Fix: "Include in RSS/Atom feeds" setting wouldn't save
= 1.0.1 =
* Fix: Button type wasn't respected
= 1.0.0 =
* New Feature: Add additional tags to Flattr buttons to make your things appear better in the Flattr catalog. Defaults to add the "blog" tag.
* Fix: The payment links in RSS/Atom feeds will now point directly to Flattr.com to make it easier for clients to detect flattrable posts
* Fix: Compatibility with WP_DEBUG - many PHP warnings and notices has been fixed
* Fix: Some adjustments to better support PHP versions prior to 5.3 has been made
* Fix: The plugin has been stable for a long time – it's time to have the version number reflect that - welcome to 1.0.0!
= 0.99.3 =
* Fix: Feeds should now validate
= 0.99.2 =
* Fix: Wizard should work with PHP 5.2 now
= 0.99.1 =
* Important: Please skip this update if the current installed version works for you
* Important: Due to API changes all registered Flattr apps must be re-created and re-authorized (which should work like a charm now!)
* New Feature: complete rewrite for new Flattr API v2
* New Feature: new oAuth wizard
* New Feature: Payment Link entities for Atom and RSS feeds
* Fix: user based flattr buttons
* Removed: Tabbing
= 0.9.25.5 =
* Fix: Erroneous escaping in advanced thing submit (by qnrq)
= 0.9.25.4 =
* New Feature: Initial test with WP 3.2 passed
* Fix: saving option for user based flattr buttons
......@@ -189,14 +263,3 @@ Fixed tags
= 0.4 =
* First public version
== Frequently Asked Questions ==
Q: I recieve an error message when trying to (re-)authorize my blog with flattr, what's wrong?
A: Please clear session/cookie/browser cache and try again please.
== Support ==
For support requests regarding the wordpress plugin, please visit the plugin support forum: http://wordpress.org/tags/flattr?forum_id=10
For every other Flattr support request head over to the Flattr forum: http://forum.flattr.net/
......@@ -2,11 +2,12 @@
if (isset ($_GET['id'])&&
isset ($_GET['md5'])&&
isset ($_GET['flattrss_redirect'])&&
function_exists('curl_init')) {
isset ($_GET['flattrss_redirect'])) {
header('Status-Code: 307');
$flattr_domain = 'flattr.com';
$old_charset = ini_get('default_charset');
ini_set('default_charset',get_option('blog_charset'));
......@@ -28,6 +29,12 @@ if (isset ($_GET['id'])&&
}
}
$additionalTags = get_option('flattr_atags', 'blog');
if (!empty($additionalTags)) {
$tags .= ',' . $additionalTags;
}
$tags = trim($tags, ', ');
$category = get_post_meta($post['ID'], '_flattr_post_category', true);
if (empty($category)) {
$category = (get_option('user_based_flattr_buttons')&& get_user_meta(get_the_author_meta('ID'), "user_flattr_cat", true)!="")? get_user_meta(get_the_author_meta('ID'), "user_flattr_cat", true): get_option('flattr_cat');
......@@ -84,7 +91,7 @@ if (isset ($_GET['id'])&&
else
$flattr_uid = get_option('flattr_uid');
$location = "https://flattr.com/submit/auto?user_id=".urlencode($flattr_uid).
$location = "https://" . $flattr_domain . "/submit/auto?user_id=".urlencode($flattr_uid).
"&url=".urlencode($url).
"&title=".urlencode($title).
"&description=".urlencode($content).
......
<div class="wrap">
<h2><?php _e('Flattr Settings'); ?></h2>
<h3>Confirm new Flattr connection</h3>
<table class="form-table">
<tr valign="top">
<th scope="row"><?php _e('Your current Flattr connection'); ?></th>
<td>
<?php if (get_option('flattr_uid')) { ?>
<?php
if (preg_match('[A-Za-z-_.]', get_option('flattr_uid'))) {
?><a href="<?php echo esc_url( 'https://flattr.com/profile/' . get_option('flattr_uid') ); ?>"><?php
esc_html_e(get_option('flattr_uid'));
?></a> <?php
}
else {
esc_html_e(get_option('flattr_uid'));
}
?>
<?php } else { ?>
-
<?php } ?>
</td>
</tr>
<tr valign="top">
<th scope="row"><?php _e('Your new Flattr connection'); ?></th>
<td>
<a href="<?php echo esc_url( 'https://flattr.com/profile/' . $_GET['FlattrUsername'] ); ?>"><?php esc_html_e($_GET['FlattrUsername']); ?></a>
</td>
</tr>
</table>
<form method="post" action="options.php">
<p class="submit">
<?php
// Replicating settings_fields
echo "<input type='hidden' name='option_page' value='flattr-settings-uid-group' />";
echo '<input type="hidden" name="action" value="update" />';
wp_nonce_field("flattr-settings-uid-group-options", '_wpnonce', false);
?>
<input type="hidden" value="<?php esc_attr_e(remove_query_arg(array('FlattrId', 'FlattrUsername'))); ?>" name="_wp_http_referer">
<input type="hidden" name="flattr_uid" value="<?php esc_attr_e($_GET['FlattrUsername']); ?>" />
<input type="submit" class="button-primary" value="<?php _e('Accept') ?>" />
</p>
</form>
</div>
This diff is collapsed.
</table>
<p class="submit">
<input type="submit" class="button-primary" value="Save Changes" />
</p>
</form>
</div>
<div id="dialog" title="Wordpress Flattr Plugin <?=Flattr::VERSION;?>">
Before the autosubmit-feature can be activated we need to run some basic tests.
</div>
</div>
\ No newline at end of file
<?php
/**
* Description:
*
* Description goes here...
*
* @author Michael Henke (aphex3k@gmail.com)
*/
?>
<div class="wrap flattr-wrap">
<div>
<div style="float:right;margin-left: 10px;"><img src="../wp-content/plugins/flattr/img/flattr-logo-beta-small.png" alt="Flattr Beta Logo"/><br />
<ul style="margin-top: 10px;">
<li style="display: inline;">
<?php Flattr::getInstance()->admin_script(); ?>
<a class="FlattrButton" href="http://wordpress.org/extend/plugins/flattr/" title="Wordpress Flattr plugin" lang="en_GB"
rel="flattr;uid:der_michael;category:software;tags:wordpress,plugin,flattr,rss;button:compact;">
Give your readers the opportunity to Flattr your effort. See http://wordpress.org/extend/plugins/flattr/ for details.
</a>
</li>
<li style="display: inline-block;position:relative; top: -6px;"><a href="https://flattr.com/donation/give/to/der_michael" style="color:#ffffff;text-decoration:none;background-image: url('<?php echo get_bloginfo('wpurl');?>/wp-content/plugins/flattr/img/bg-boxlinks-green.png');border-radius:3px;text-shadow:#666666 0 1px 1px;width:53px;padding:1px;padding-top: 2px;padding-bottom: 2px;display:block;text-align:center;font-weight: bold;" target="_blank">Donate</a></li>
</ul>
</div>
<div id="icon-options-general" class="icon32 flattr"><br></div>
<h2><?php _e('Flattr Settings'); ?></h2>
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* Copyright (c) 2006 Patrick Fitzgerald */
function tabberObj(argsObj)
{var arg;this.div=null;this.classMain="tabber";this.classMainLive="tabberlive";this.classTab="tabbertab";this.classTabDefault="tabbertabdefault";this.classNav="tabbernav";this.classTabHide="tabbertabhide";this.classNavActive="tabberactive";this.titleElements=['h2','h3','h4','h5','h6'];this.titleElementsStripHTML=true;this.removeTitle=true;this.addLinkId=false;this.linkIdFormat='<tabberid>nav<tabnumberone>';for(arg in argsObj){this[arg]=argsObj[arg];}
this.REclassMain=new RegExp('\\b'+this.classMain+'\\b','gi');this.REclassMainLive=new RegExp('\\b'+this.classMainLive+'\\b','gi');this.REclassTab=new RegExp('\\b'+this.classTab+'\\b','gi');this.REclassTabDefault=new RegExp('\\b'+this.classTabDefault+'\\b','gi');this.REclassTabHide=new RegExp('\\b'+this.classTabHide+'\\b','gi');this.tabs=new Array();if(this.div){this.init(this.div);this.div=null;}}
tabberObj.prototype.init=function(e)
{var
childNodes,i,i2,t,defaultTab=0,DOM_ul,DOM_li,DOM_a,aId,headingElement;if(!document.getElementsByTagName){return false;}
if(e.id){this.id=e.id;}
this.tabs.length=0;childNodes=e.childNodes;for(i=0;i<childNodes.length;i++){if(childNodes[i].className&&childNodes[i].className.match(this.REclassTab)){t=new Object();t.div=childNodes[i];this.tabs[this.tabs.length]=t;if(childNodes[i].className.match(this.REclassTabDefault)){defaultTab=this.tabs.length-1;}}}
DOM_ul=document.createElement("ul");DOM_ul.className=this.classNav;for(i=0;i<this.tabs.length;i++){t=this.tabs[i];t.headingText=t.div.title;if(this.removeTitle){t.div.title='';}
if(!t.headingText){for(i2=0;i2<this.titleElements.length;i2++){headingElement=t.div.getElementsByTagName(this.titleElements[i2])[0];if(headingElement){t.headingText=headingElement.innerHTML;if(this.titleElementsStripHTML){t.headingText.replace(/<br>/gi," ");t.headingText=t.headingText.replace(/<[^>]+>/g,"");}
break;}}}
if(!t.headingText){t.headingText=i+1;}
DOM_li=document.createElement("li");t.li=DOM_li;DOM_a=document.createElement("a");DOM_a.appendChild(document.createTextNode(t.headingText));DOM_a.href="javascript:void(null);";DOM_a.title=t.headingText;DOM_a.onclick=this.navClick;DOM_a.tabber=this;DOM_a.tabberIndex=i;if(this.addLinkId&&this.linkIdFormat){aId=this.linkIdFormat;aId=aId.replace(/<tabberid>/gi,this.id);aId=aId.replace(/<tabnumberzero>/gi,i);aId=aId.replace(/<tabnumberone>/gi,i+1);aId=aId.replace(/<tabtitle>/gi,t.headingText.replace(/[^a-zA-Z0-9\-]/gi,''));DOM_a.id=aId;}
DOM_li.appendChild(DOM_a);DOM_ul.appendChild(DOM_li);}
e.insertBefore(DOM_ul,e.firstChild);e.className=e.className.replace(this.REclassMain,this.classMainLive);this.tabShow(defaultTab);if(typeof this.onLoad=='function'){this.onLoad({tabber:this});}
return this;};tabberObj.prototype.navClick=function(event)
{var
rVal,a,self,tabberIndex,onClickArgs;a=this;if(!a.tabber){return false;}
self=a.tabber;tabberIndex=a.tabberIndex;a.blur();if(typeof self.onClick=='function'){onClickArgs={'tabber':self,'index':tabberIndex,'event':event};if(!event){onClickArgs.event=window.event;}
rVal=self.onClick(onClickArgs);if(rVal===false){return false;}}
self.tabShow(tabberIndex);return false;};tabberObj.prototype.tabHideAll=function()
{var i;for(i=0;i<this.tabs.length;i++){this.tabHide(i);}};tabberObj.prototype.tabHide=function(tabberIndex)
{var div;if(!this.tabs[tabberIndex]){return false;}
div=this.tabs[tabberIndex].div;if(!div.className.match(this.REclassTabHide)){div.className+=' '+this.classTabHide;}
this.navClearActive(tabberIndex);return this;};tabberObj.prototype.tabShow=function(tabberIndex)
{var div;if(!this.tabs[tabberIndex]){return false;}
this.tabHideAll();div=this.tabs[tabberIndex].div;div.className=div.className.replace(this.REclassTabHide,'');this.navSetActive(tabberIndex);if(typeof this.onTabDisplay=='function'){this.onTabDisplay({'tabber':this,'index':tabberIndex});}
return this;};tabberObj.prototype.navSetActive=function(tabberIndex)
{this.tabs[tabberIndex].li.className=this.classNavActive;return this;};tabberObj.prototype.navClearActive=function(tabberIndex)
{this.tabs[tabberIndex].li.className='';return this;};function tabberAutomatic(tabberArgs)
{var
tempObj,divs,i;if(!tabberArgs){tabberArgs={};}
tempObj=new tabberObj(tabberArgs);divs=document.getElementsByTagName("div");for(i=0;i<divs.length;i++){if(divs[i].className&&divs[i].className.match(tempObj.REclassMain)){tabberArgs.div=divs[i];divs[i].tabber=new tabberObj(tabberArgs);}}
return this;}
function tabberAutomaticOnLoad(tabberArgs)
{var oldOnLoad;if(!tabberArgs){tabberArgs={};}
oldOnLoad=window.onload;if(typeof window.onload!='function'){window.onload=function(){tabberAutomatic(tabberArgs);};}else{window.onload=function(){oldOnLoad();tabberAutomatic(tabberArgs);};}}
if(typeof tabberOptions=='undefined'){tabberAutomaticOnLoad();}else{if(!tabberOptions['manualStartup']){tabberAutomaticOnLoad(tabberOptions);}}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment