Committing contributed code by Matthias Glastra: Mostly coding conventions related...
[project/addthis.git] / classes / AddThis.php
1 <?php
2 /**
3 * @file
4 * An AddThis-class.
5 *
6 * @author Jani Palsamäki
7 */
8
9 class AddThis {
10
11 const BLOCK_NAME = 'addthis_block';
12 const DEFAULT_CUSTOM_CONFIGURATION_CODE = 'var addthis_config = {}';
13 const DEFAULT_FORMATTER = 'addthis_default_formatter';
14 const DEFAULT_NUMBER_OF_PREFERRED_SERVICES = 4;
15 const FIELD_TYPE = 'addthis';
16 const MODULE_NAME = 'addthis';
17 const PERMISSION_ADMINISTER_ADDTHIS = 'administer addthis';
18 const PERMISSION_ADMINISTER_ADVANCED_ADDTHIS = 'administer advanced addthis';
19 const STYLE_KEY = 'addthis_style';
20 const WIDGET_TYPE = 'addthis_button_widget';
21
22 // AddThis attribute and parameter names (as defined in AddThis APIs)
23 const PROFILE_ID_QUERY_PARAMETER = 'pubid';
24 const TITLE_ATTRIBUTE = 'addthis:title';
25
26 // Persistent variable keys
27 const ADDRESSBOOK_ENABLED_KEY = 'addthis_addressbook_enabled';
28 const BLOCK_WIDGET_TYPE_KEY = 'addthis_block_widget_type';
29 const BOOKMARK_URL_KEY = 'addthis_bookmark_url';
30 const CLICKBACK_TRACKING_ENABLED_KEY = 'addthis_clickback_tracking_enabled';
31 const CLICK_TO_OPEN_COMPACT_MENU_ENABLED_KEY = 'addthis_click_to_open_compact_menu_enabled';
32 const CO_BRAND_KEY = 'addthis_co_brand';
33 const COMPLIANT_508_KEY = 'addthis_508_compliant';
34 const CUSTOM_CONFIGURATION_CODE_ENABLED_KEY = 'addthis_custom_configuration_code_enabled';
35 const CUSTOM_CONFIGURATION_CODE_KEY = 'addthis_custom_configuration_code';
36 const ENABLED_SERVICES_KEY = 'addthis_enabled_services';
37 const FACEBOOK_LIKE_ENABLED_KEY = 'addthis_facebook_like_enabled';
38 const GOOGLE_PLUS_ONE_ENABLED_KEY = 'addthis_google_plus_one_enabled';
39 const LARGE_ICONS_ENABLED_KEY = 'addthis_large_icons_enabled';
40 const NUMBER_OF_PREFERRED_SERVICES_KEY = 'addthis_number_of_preferred_services';
41 const OPEN_WINDOWS_ENABLED_KEY = 'addthis_open_windows_enabled';
42 const PROFILE_ID_KEY = 'addthis_profile_id';
43 const SERVICES_CSS_URL_KEY = 'addthis_services_css_url';
44 const SERVICES_JSON_URL_KEY = 'addthis_services_json_url';
45 const STANDARD_CSS_ENABLED_KEY = 'addthis_standard_css_enabled';
46 const TWITTER_ENABLED_KEY = 'addthis_twitter_enabled';
47 const UI_DELAY_KEY = 'addthis_ui_delay';
48 const UI_HEADER_BACKGROUND_COLOR_KEY = 'addthis_ui_header_background_color';
49 const UI_HEADER_COLOR_KEY = 'addthis_ui_header_color';
50 const WIDGET_JS_URL_KEY = 'addthis_widget_js_url';
51
52 // External resources
53 const DEFAULT_BOOKMARK_URL = 'http://www.addthis.com/bookmark.php?v=250';
54 const DEFAULT_SERVICES_CSS_URL = 'http://cache.addthiscdn.com/icons/v1/sprites/services.css';
55 const DEFAULT_SERVICES_JSON_URL = 'http://cache.addthiscdn.com/services/v1/sharing.en.json';
56 const DEFAULT_WIDGET_JS_URL = 'http://s7.addthis.com/js/250/addthis_widget.js';
57
58 // Internal resources
59 const ADMIN_CSS_FILE = 'addthis.admin.css';
60 const ADMIN_INCLUDE_FILE = 'includes/addthis.admin.inc';
61
62 // Widget types
63 const WIDGET_TYPE_COMPACT_BUTTON = 'compact_button';
64 const WIDGET_TYPE_DISABLED = 'disabled';
65 const WIDGET_TYPE_LARGE_BUTTON = 'large_button';
66 const WIDGET_TYPE_SHARECOUNT = 'sharecount';
67 const WIDGET_TYPE_TOOLBOX = 'toolbox';
68
69 private static $instance;
70
71 /* @var AddThisConfigurationGenerator */
72 private $configurationGenerator;
73
74 /* @var AddThisJson */
75 private $json;
76
77 /* @var AddThisMarkupGenerator */
78 private $markupGenerator;
79
80 /**
81 * @return AddThis
82 */
83 public static function getInstance() {
84 if (!isset(self::$instance)) {
85 $addThis = new AddThis();
86 $addThis->setAddThisConfigurationGenerator(new AddThisConfigurationGenerator());
87 $addThis->setJson(new AddThisJson());
88 $addThis->setMarkupGenerator(new AddThisMarkupGenerator());
89 self::$instance = $addThis;
90 }
91 return self::$instance;
92 }
93
94 public function setAddThisConfigurationGenerator(AddThisConfigurationGenerator $configurationGenerator) {
95 $this->configurationGenerator = $configurationGenerator;
96 }
97
98 public function setJson(AddThisJson $json) {
99 $this->json = $json;
100 }
101
102 public function setMarkupGenerator(AddThisMarkupGenerator $markupGenerator) {
103 $this->markupGenerator = $markupGenerator;
104 }
105
106 public function getWidgetTypes() {
107 return array(
108 self::WIDGET_TYPE_DISABLED => t('Disabled'),
109 self::WIDGET_TYPE_COMPACT_BUTTON => t('Compact button'),
110 self::WIDGET_TYPE_LARGE_BUTTON => t('Large button'),
111 self::WIDGET_TYPE_TOOLBOX => t('Toolbox'),
112 self::WIDGET_TYPE_SHARECOUNT => t('Sharecount'),
113 );
114 }
115
116 public function getBlockWidgetType() {
117 return variable_get(self::BLOCK_WIDGET_TYPE_KEY, self::WIDGET_TYPE_COMPACT_BUTTON);
118 }
119
120 public function getWidgetMarkup($widgetType = '', $entity = NULL) {
121 $markup = '';
122 if (self::WIDGET_TYPE_LARGE_BUTTON == $widgetType) {
123 $markup = $this->getLargeButtonWidgetMarkup($entity);
124 } elseif (self::WIDGET_TYPE_COMPACT_BUTTON == $widgetType) {
125 $markup = $this->getCompactButtonWidgetMarkup($entity);
126 } elseif (self::WIDGET_TYPE_TOOLBOX == $widgetType) {
127 $markup = $this->getToolboxWidgetMarkup($entity);
128 } elseif (self::WIDGET_TYPE_SHARECOUNT == $widgetType) {
129 $markup = $this->getSharecountWidgetMarkup($entity);
130 }
131 return $markup;
132 }
133
134 public function getProfileId() {
135 return check_plain(variable_get(AddThis::PROFILE_ID_KEY));
136 }
137
138 public function getServicesCssUrl() {
139 return check_url(variable_get(AddThis::SERVICES_CSS_URL_KEY, self::DEFAULT_SERVICES_CSS_URL));
140 }
141
142 public function getServicesJsonUrl() {
143 return check_url(variable_get(AddThis::SERVICES_JSON_URL_KEY, self::DEFAULT_SERVICES_JSON_URL));
144 }
145
146 public function getServices() {
147 $rows = array();
148 $services = $this->json->decode($this->getServicesJsonUrl());
149 if (empty($services)) {
150 drupal_set_message(t('AddThis services could not be loaded from ' . $this->getServicesJsonUrl()), 'warning');
151 } else {
152 foreach ($services['data'] AS $service) {
153 $serviceCode = check_plain($service['code']);
154 $serviceName = check_plain($service['name']);
155 $rows[$serviceCode] = '<span class="addthis_service_icon icon_' . $serviceCode . '"></span> ' . $serviceName;
156 }
157 }
158 return $rows;
159 }
160
161 public function getEnabledServices() {
162 return variable_get(self::ENABLED_SERVICES_KEY, array());
163 }
164
165 public function addStylesheets() {
166 drupal_add_css($this->getServicesCssUrl(), 'external');
167 drupal_add_css($this->getAdminCssFilePath(), 'file');
168 }
169
170 public function addWidgetJs() {
171 drupal_add_js(self::getWidgetUrl(), array('type' => 'external', 'scope' => 'footer'));
172 }
173
174 public function addConfigurationOptionsJs() {
175 if ($this->isCustomConfigurationCodeEnabled()) {
176 $javascript = $this->getCustomConfigurationCode();
177 } else {
178 $enabledServices = $this->getServiceNamesAsCommaSeparatedString() . 'more';
179 $javascript = 'var addthis_config = {'
180 . $this->configurationGenerator->generate('services_compact', $enabledServices)
181 . $this->configurationGenerator->generate('data_track_clickback', $this->isClickbackTrackingEnabled())
182 . $this->configurationGenerator->generate('ui_508_compliant', $this->get508Compliant())
183 . $this->configurationGenerator->generate('ui_click', $this->isClickToOpenCompactMenuEnabled())
184 . $this->configurationGenerator->generate('ui_cobrand', $this->getCoBrand())
185 . $this->configurationGenerator->generate('ui_delay', $this->getUiDelay())
186 . $this->configurationGenerator->generate('ui_header_background', $this->getUiHeaderBackgroundColor())
187 . $this->configurationGenerator->generate('ui_header_color', $this->getUiHeaderColor())
188 . $this->configurationGenerator->generate('ui_open_windows', $this->isOpenWindowsEnabled())
189 . $this->configurationGenerator->generate('ui_use_css', $this->isStandardCssEnabled())
190 . $this->configurationGenerator->generateWithoutTrailingComma('ui_use_addressbook', $this->isAddressbookEnabled())
191 . '}'
192 ;
193 }
194 drupal_add_js($javascript, array('type' => 'inline'));
195 }
196
197 public function areLargeIconsEnabled() {
198 return (boolean) variable_get(self::LARGE_ICONS_ENABLED_KEY, TRUE);
199 }
200
201 public function isClickToOpenCompactMenuEnabled() {
202 return (boolean) variable_get(self::CLICK_TO_OPEN_COMPACT_MENU_ENABLED_KEY, FALSE);
203 }
204
205 public function isOpenWindowsEnabled() {
206 return (boolean) variable_get(self::OPEN_WINDOWS_ENABLED_KEY, FALSE);
207 }
208
209 public function isFacebookLikeEnabled() {
210 return (boolean) variable_get(self::FACEBOOK_LIKE_ENABLED_KEY, FALSE);
211 }
212
213 public function isGooglePlusOneEnabled() {
214 return (boolean) variable_get(self::GOOGLE_PLUS_ONE_ENABLED_KEY, FALSE);
215 }
216
217 public function isTwitterEnabled() {
218 return (boolean) variable_get(self::TWITTER_ENABLED_KEY, FALSE);
219 }
220
221 public function getUiDelay() {
222 return (int) check_plain(variable_get(self::UI_DELAY_KEY));
223 }
224
225 public function getUiHeaderColor() {
226 return check_plain(variable_get(self::UI_HEADER_COLOR_KEY));
227 }
228
229 public function getUiHeaderBackgroundColor() {
230 return check_plain(variable_get(self::UI_HEADER_BACKGROUND_COLOR_KEY));
231 }
232
233 public function isStandardCssEnabled() {
234 return (boolean) variable_get(self::STANDARD_CSS_ENABLED_KEY, TRUE);
235 }
236
237 public function getCustomConfigurationCode() {
238 return variable_get(self::CUSTOM_CONFIGURATION_CODE_KEY, self::DEFAULT_CUSTOM_CONFIGURATION_CODE);
239 }
240
241 public function isCustomConfigurationCodeEnabled() {
242 return (boolean) variable_get(self::CUSTOM_CONFIGURATION_CODE_ENABLED_KEY, FALSE);
243 }
244
245 public function getBaseWidgetJsUrl() {
246 return check_url(variable_get(self::WIDGET_JS_URL_KEY, self::DEFAULT_WIDGET_JS_URL));
247 }
248
249 public function getBaseBookmarkUrl() {
250 return check_url(variable_get(self::BOOKMARK_URL_KEY, self::DEFAULT_BOOKMARK_URL));
251 }
252
253 public function getNumberOfPreferredServices() {
254 return variable_get(self::NUMBER_OF_PREFERRED_SERVICES_KEY, self::DEFAULT_NUMBER_OF_PREFERRED_SERVICES);
255 }
256
257 public function getCoBrand() {
258 return variable_get(self::CO_BRAND_KEY);
259 }
260
261 public function get508Compliant() {
262 return (boolean) variable_get(self::COMPLIANT_508_KEY, FALSE);
263 }
264
265 public function isClickbackTrackingEnabled() {
266 return (boolean) variable_get(self::CLICKBACK_TRACKING_ENABLED_KEY, FALSE);
267 }
268
269 public function isAddressbookEnabled() {
270 return (boolean) variable_get(self::ADDRESSBOOK_ENABLED_KEY, FALSE);
271 }
272
273 private function getLargeButtonWidgetMarkup($entity) {
274 return '<a class="addthis_button" '
275 . $this->getAddThisAttributesMarkup($entity)
276 . $this->markupGenerator->generateAttribute('href', self::getFullBookmarkUrl())
277 . '><img src="http://s7.addthis.com/static/btn/v2/lg-share-en.gif" width="125" height="16" alt="'
278 . t('Bookmark and Share')
279 . '" style="border:0"/></a>';
280 }
281
282 private function getCompactButtonWidgetMarkup($entity) {
283 return '<a class="addthis_button" '
284 . self::getAddThisAttributesMarkup($entity)
285 . $this->markupGenerator->generateAttribute('href', $this->getFullBookmarkUrl())
286 . '><img src="http://s7.addthis.com/static/btn/sm-share-en.gif" width="83" height="16" alt="'
287 . t('Bookmark and Share')
288 . '" style="border:0"/></a>';
289 }
290
291 private function getToolboxWidgetMarkup($entity) {
292 $markup = '<div class="addthis_toolbox addthis_default_style '
293 . $this->getLargeButtonsClass()
294 . '" '
295 . $this->getAddThisAttributesMarkup($entity)
296 . '><a '
297 . $this->markupGenerator->generateAttribute('href', $this->getFullBookmarkUrl())
298 . ' class="addthis_button_compact"></a>';
299
300 $numberOfPreferredServices = self::getNumberOfPreferredServices();
301
302 for ($i = 1; $i <= $numberOfPreferredServices; $i++) {
303 $markup .= "<a class=\"addthis_button_preferred_$i\"></a>";
304 }
305
306 $markup .= $this->getTwitterButtonMarkup();
307 $markup .= $this->getFacebookLikeButtonMarkup();
308 $markup .= $this->getGooglePlusOneButtonMarkup();
309 $markup .= '</div>';
310
311 return $markup;
312 }
313
314 private function getSharecountWidgetMarkup($entity) {
315 return '<div class="addthis_toolbox addthis_default_style"><a class="addthis_counter" '
316 . $this->getAddThisAttributesMarkup($entity)
317 . '></a></div>';
318 }
319
320 private function getAddThisAttributesMarkup($entity) {
321 if (is_object($entity)) {
322 return $this->getAddThisTitleAttributeMarkup($entity) . ' ';
323 }
324 return '';
325 }
326
327 private function getAddThisTitleAttributeMarkup($entity) {
328 return $this->markupGenerator->generateAttribute(
329 self::TITLE_ATTRIBUTE, drupal_get_title() . ' - ' . check_plain($entity->title)
330 );
331 }
332
333 private function getLargeButtonsClass() {
334 return $this->areLargeIconsEnabled() ? ' addthis_32x32_style ' : '';
335 }
336
337 private function getTwitterButtonMarkup() {
338 $markup = '';
339 if ($this->isTwitterEnabled()) {
340 $markup = '<a class="addthis_button_tweet"></a>';
341 }
342 return $markup;
343 }
344
345 private function getFacebookLikeButtonMarkup() {
346 $markup = '';
347 if ($this->isFacebookLikeEnabled()) {
348 $markup = '<a class="addthis_button_facebook_like" fb:like:layout="button_count"></a>';
349 }
350 return $markup;
351 }
352
353 private function getGooglePlusOneButtonMarkup() {
354 $markup = '';
355 if ($this->isGooglePlusOneEnabled()) {
356 $markup = '<a class="addthis_button_google_plusone"></a>';
357 }
358 return $markup;
359 }
360
361 private function getServiceNamesAsCommaSeparatedString() {
362 $enabledServiceNames = array_values($this->getEnabledServices());
363 $enabledServicesAsCommaSeparatedString = '';
364 foreach ($enabledServiceNames as $enabledServiceName) {
365 if ($enabledServiceName != '0') {
366 $enabledServicesAsCommaSeparatedString .= $enabledServiceName . ',';
367 }
368 }
369 return $enabledServicesAsCommaSeparatedString;
370 }
371
372 private function getAdminCssFilePath() {
373 return drupal_get_path('module', self::MODULE_NAME) . '/' . self::ADMIN_CSS_FILE;
374 }
375
376 private function getFullBookmarkUrl() {
377 return check_url($this->getBaseBookmarkUrl() . $this->getProfileIdQueryParameterPrefixedWithAmp());
378 }
379
380 private function getProfileIdQueryParameter($prefix) {
381 $profileId = $this->getProfileId();
382 return !empty($profileId) ? $prefix . self::PROFILE_ID_QUERY_PARAMETER . '=' . $profileId : '';
383 }
384
385 private function getProfileIdQueryParameterPrefixedWithAmp() {
386 return $this->getProfileIdQueryParameter('&');
387 }
388
389 private function getProfileIdQueryParameterPrefixedWithHash() {
390 return $this->getProfileIdQueryParameter('#');
391 }
392
393 private function getWidgetUrl() {
394 return check_url($this->getBaseWidgetJsUrl() . $this->getProfileIdQueryParameterPrefixedWithHash());
395 }
396 }