Révision 2c8c2b87
Ajouté par Assos Assos il y a presque 9 ans
drupal7/sites/all/modules/addthis/CHANGELOG.txt | ||
---|---|---|
1 |
# 7.x-4.0-alpha6 |
|
2 |
Use update.php to rebuild the registry because of class changes. |
|
3 |
If that does not work use the rebuild_registry module. |
|
4 |
|
|
5 |
More importantly classes have been restructured and javascript loading |
|
6 |
has been redesigned. |
|
7 |
|
|
8 |
- Restructured test classes. |
|
9 |
- Restructured the way widget.js is included, how loading is done and |
|
10 |
how the addthis.js behaves. |
|
11 |
- The addthis.js is always loaded but is used as a library instead of |
|
12 |
executing everything directly like it was before. |
|
13 |
- The include of AddThisJson and AddThisWidgetJs in AddThis::getInstance() |
|
14 |
where removed because they should be autoloaded from the register. |
|
15 |
|
|
16 |
Restructuring classes. |
|
17 |
- In general the AddThis class has become a sort of module file that contains |
|
18 |
all kinds of addthis related functions. This is bad design and therefore step |
|
19 |
by step things are refactored. This breaks API but no official rc or release |
|
20 |
has been given out yet. |
|
21 |
- Classes are structured now in folders in a way namespace could be organised. |
|
22 |
Because PHP 5.2 does not support namespaces we only use classes but the |
|
23 |
structure is already there for future portability. |
|
24 |
- AddThisScriptManager is added as a Service. This handles the attachment of |
|
25 |
js and settings when needing addthis or widgets on your page. The AddThis->addWidgetJs, |
|
26 |
AddThis->includeWidgetJs and AddThis->addConfigurationOptionsJs where |
|
27 |
removed in favor of the AddThisScriptManager functionality. |
|
28 |
- AddThisJson is moved to the Util directory. |
|
29 |
- AddThisWidgetJs is renamed to AddThisWidgetJsUrl and moved to the Util |
|
30 |
directory. The name changed because it better displays the purpose of the |
|
31 |
class. |
|
32 |
- AddThis->getServiceNamesAsCommaSeparatedString was made public to be usable |
|
33 |
inside the AddThisScriptManager. |
|
34 |
- getWidgetJsLoadType was renamed to getWidgetJsInclude because it displays |
|
35 |
the type of information better. |
|
36 |
- Related to the previous the WIDGET_JS_LOAD_TYPE was removed and split into |
|
37 |
WIDGET_JS_LOAD_DOMREADY, WIDGET_JS_LOAD_ASYNC and WIDGET_JS_INCLUDE. The |
|
38 |
reason beeing that the old way was misinterpreted. The DOMREADY and ASYNC |
|
39 |
type of loading are two different things but where not possible separately. |
|
40 |
|
|
41 |
Examples |
|
42 |
- Expanded the example with a hook_page_build to run the attach functionality |
|
43 |
on the whole page. |
|
44 |
|
|
45 |
Test |
|
46 |
- A test module was added to be able to test extra things but seperate it from |
|
47 |
the main module. |
|
48 |
- addthis.test contained two test classes. These where split into two sperate |
|
49 |
files. |
|
50 |
|
|
51 |
# 7.x-4.0-alpha5 |
|
52 |
Some undefined index where fixed on the block save for disabled display. |
|
53 |
|
|
54 |
- Unsupported operand types on block save. [#2181367] |
|
55 |
- Minor changes to the documentation. |
|
56 |
- Fixed issue #1943896 by fcjversc: Add Linkedin vertical counter. |
|
57 |
- Fixed issue #2247245 by jmuzz: Implement button orientation option for Facebook Share button. |
|
58 |
- Fixed issue #2250109 by matglas86, jmuzz: Add support for individual share counters. |
|
59 |
- Fixed issue #2233585 by matglas86, mstef: Uncaught TypeError: Object #<Object> has no method 'ready' . |
|
60 |
- Fixed issue #2206515 by matglas86, dubois: Add configuration 'services_excluded' (globally excluded services) to AddThis Basic Settings. |
|
61 |
- Fixed issue #1989152 by matglas86, labue, juampy: Allow alterations to 'addthis_share' variable in 'addthis_configuration' alter hook. |
|
62 |
- Fixed issue #2241967: Invalid preferred services on form validation. |
|
63 |
- Issue #2181367 by matglas86, dubois | 4fs: Error Fatal error: Unsupported operand types. |
|
64 |
|
|
65 |
# 7.x-4.0-alpha4 |
|
66 |
Fixed two nasty bugs in 7.x-4.0-alpha3. |
|
67 |
|
|
68 |
- Undefined index: button_size & Undefined index: extra_css. [#2174975] |
|
69 |
- Double colon :: changed to -> because addWidgetJs was not static. [#2174771] |
|
70 |
|
|
1 | 71 |
# 7.x-4.0-alpha3 |
2 | 72 |
|
3 | 73 |
Major changes |
drupal7/sites/all/modules/addthis/README.txt | ||
---|---|---|
1 | 1 |
|
2 | 2 |
-- SUMMARY -- |
3 | 3 |
|
4 |
Add This module provides Drupal integration to addthis.com link sharing service. Integration has been implemented as a field. |
|
4 |
Add This module provides Drupal integration to addthis.com link sharing service. |
|
5 |
Integration has been implemented as a field. |
|
5 | 6 |
|
6 | 7 |
Description from addthis.com: |
7 |
The AddThis button spreads your content across the Web by making it easier for your visitors to bookmark and |
|
8 |
share it with other people, again... and again... and again. This simple yet powerful button is very easy to |
|
9 |
install and provides valuable Analytics about the bookmarking and sharing activity of your users. AddThis helps |
|
10 |
your visitors create a buzz for your site and increase its popularity and ranking. |
|
11 |
|
|
12 |
AddThis is already on hundreds of thousands of websites including SAP, TIME Magazine, Oracle, Freewebs, |
|
13 |
Entertainment Weekly, Topix, Lonely Planet, MapQuest, MySpace, PGA Tour, Tower Records, Squidoo, Zappos, Funny |
|
14 |
or Die, FOX, ABC, CBS, Glamour, PostSecret, WebMD, American Idol, and ReadWriteWeb, just to name a few. Each |
|
15 |
month our button is displayed 20 billion times. |
|
8 |
The AddThis button spreads your content across the Web by making it easier for |
|
9 |
your visitors to bookmark and share it with other people, again... and again... |
|
10 |
and again. This simple yet powerful button is very easy to install and provides |
|
11 |
valuable Analytics about the bookmarking and sharing activity of your users. |
|
12 |
AddThis helps your visitors create a buzz for your site and increase its |
|
13 |
popularity and ranking. |
|
14 |
|
|
15 |
AddThis is already on hundreds of thousands of websites including SAP, |
|
16 |
TIME Magazine, Oracle, Freewebs, Entertainment Weekly, Topix, Lonely Planet, |
|
17 |
MapQuest, MySpace, PGA Tour, Tower Records, Squidoo, Zappos, Funny or Die, FOX, |
|
18 |
ABC, CBS, Glamour, PostSecret, WebMD, American Idol, and ReadWriteWeb, |
|
19 |
just to name a few. Each month our button is displayed 20 billion times. |
|
16 | 20 |
|
17 | 21 |
-- REQUIREMENTS -- |
18 | 22 |
|
... | ... | |
20 | 24 |
|
21 | 25 |
-- INSTALLATION -- |
22 | 26 |
|
23 |
Normal Drupal module installation, see http://drupal.org/node/70151 for further information. |
|
27 |
Normal Drupal module installation, see http://drupal.org/node/70151 for further |
|
28 |
information. |
|
24 | 29 |
|
25 |
For link sharing statistics registration at http://addthis.com/ is required, but the module will work even without registration. |
|
30 |
For link sharing statistics registration at http://addthis.com/ is required, but |
|
31 |
the module will work even without registration. |
|
26 | 32 |
|
27 | 33 |
-- CONFIGURATION -- |
28 | 34 |
|
29 | 35 |
Use the admin configuration page to configure settings and see http://drupal.org/node/1309922 |
30 | 36 |
for a walkthrough on how to configure the rest. |
31 | 37 |
|
38 |
-- DEVELOPMENT -- |
|
39 |
|
|
40 |
Please see the addthis.api.php for implementation options of different displays |
|
41 |
and altering configuration on rendering. |
|
32 | 42 |
|
33 | 43 |
-- CONTACT -- |
34 | 44 |
|
drupal7/sites/all/modules/addthis/TODO.txt | ||
---|---|---|
1 |
- Update README.txt to refer to the addthis.api.php for implementation options. |
|
2 |
- Write addthis.api.php file with example of implementation. |
|
3 | 1 |
- Add custom button with upload functionality for a custom button image. |
4 | 2 |
- Move basic button to main module to provide a basic implementation. |
5 |
- Create a column view of the services on the settings page. |
|
6 | 3 |
- Create asynchronous load checkbox in settings page. |
7 | 4 |
- Refactor the order of methods in the AddThis class to collect same type of methods. |
5 |
- Refactor the rendering into classes per display type. |
|
6 |
- Delegate settings save validation to it corresponding display type class. |
drupal7/sites/all/modules/addthis/addthis.admin.css | ||
---|---|---|
1 | 1 |
.addthis_service_icon { |
2 | 2 |
display: inline-block; |
3 | 3 |
padding-left: 20px; |
4 |
} |
|
4 |
} |
|
5 |
#edit-addthis-enabled-services .form-item, #edit-addthis-excluded-services .form-item { |
|
6 |
float: left; |
|
7 |
width: 20%; |
|
8 |
} |
|
9 |
#edit-addthis-enabled-services .form-item .description { |
|
10 |
clear: both; |
|
11 |
} |
drupal7/sites/all/modules/addthis/addthis.api.php | ||
---|---|---|
55 | 55 |
$markup['google_plusone']['#attributes']['g:plusone:size'] = 'small'; |
56 | 56 |
} |
57 | 57 |
} |
58 |
|
|
59 |
/** |
|
60 |
* Implements hook_TYPE_alter(). |
|
61 |
* |
|
62 |
* @param array $configuration. |
|
63 |
*/ |
|
64 |
function hook_addthis_configuration($configuration) { |
|
65 |
|
|
66 |
if (isset($configuration['templates'])) { |
|
67 |
$configuration['templates']['twitter'] = 'Hello on twitter.'; |
|
68 |
} |
|
69 |
|
|
70 |
if (isset($configuration['addthis_share'])) { |
|
71 |
// Alter the share variable used for the javascript. |
|
72 |
} |
|
73 |
} |
drupal7/sites/all/modules/addthis/addthis.example.php | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
/** |
|
4 |
* Implements hook_page_build(). |
|
5 |
*/ |
|
6 |
function hook_page_build(&$page) { |
|
7 |
|
|
8 |
// Load the scripts on a specific url or other case when you don't use the |
|
9 |
// Field API or Block. |
|
10 |
if (current_path() == 'node/1') { |
|
11 |
$manager = AddThisScriptManager::getInstance(); |
|
12 |
|
|
13 |
// Adjust domready and async settings for this page. |
|
14 |
// |
|
15 |
// NOTE! that on pages where these settings are altered and attach is called |
|
16 |
// more then once but not altered he second time, you will get conflicts. |
|
17 |
// The widget js will be loaded multiple times with different settings. |
|
18 |
// So choose wisely! |
|
19 |
// |
|
20 |
$manager->setAsync(FALSE); |
|
21 |
$manager->setDomReady(FALSE); |
|
22 |
|
|
23 |
// Using $page['content'] or other area is neccesary because otherwise |
|
24 |
// #attached does not work. You can not attach on $page directly. |
|
25 |
$manager->attachJsToElement($page['content']); |
|
26 |
} |
|
27 |
} |
drupal7/sites/all/modules/addthis/addthis.info | ||
---|---|---|
5 | 5 |
|
6 | 6 |
dependencies[] = field |
7 | 7 |
|
8 |
files[] = addthis.test |
|
9 | 8 |
files[] = classes/AddThis.php |
10 |
files[] = classes/AddThisJson.php |
|
9 |
files[] = classes/Services/AddThisScriptManager.php |
|
10 |
files[] = classes/Util/AddThisJson.php |
|
11 |
files[] = classes/Util/AddThisWidgetJsUrl.php |
|
12 |
files[] = tests/AddThisTestHelper.php |
|
13 |
files[] = tests/AddThisDrupalSettingsJsTestHelper.php |
|
14 |
files[] = tests/AddThisJsTest.test |
|
15 |
files[] = tests/AddThisFunctionalityTestCase.test |
|
16 |
files[] = tests/AddThisPermissionsTestCase.test |
|
11 | 17 |
|
12 | 18 |
configure = admin/config/user-interface/addthis |
13 | 19 |
|
14 |
; Information added by Drupal.org packaging script on 2014-01-22
|
|
15 |
version = "7.x-4.0-alpha4"
|
|
20 |
; Information added by Drupal.org packaging script on 2015-06-15
|
|
21 |
version = "7.x-4.0-alpha6"
|
|
16 | 22 |
core = "7.x" |
17 | 23 |
project = "addthis" |
18 |
datestamp = "1390384409"
|
|
24 |
datestamp = "1434368594"
|
|
19 | 25 |
|
drupal7/sites/all/modules/addthis/addthis.install | ||
---|---|---|
1 | 1 |
<?php |
2 |
|
|
3 | 2 |
/** |
4 | 3 |
* @file |
5 | 4 |
* Install, update and uninstall functions for the AddThis module. |
... | ... | |
44 | 43 |
variable_del(AddThis::CUSTOM_CONFIGURATION_CODE_ENABLED_KEY); |
45 | 44 |
variable_del(AddThis::CUSTOM_CONFIGURATION_CODE_KEY); |
46 | 45 |
variable_del(AddThis::ENABLED_SERVICES_KEY); |
46 |
variable_del(AddThis::EXCLUDED_SERVICES_KEY); |
|
47 | 47 |
variable_del(AddThis::OPEN_WINDOWS_ENABLED_KEY); |
48 | 48 |
variable_del(AddThis::PROFILE_ID_KEY); |
49 | 49 |
variable_del(AddThis::SERVICES_CSS_URL_KEY); |
... | ... | |
53 | 53 |
variable_del(AddThis::UI_HEADER_BACKGROUND_COLOR_KEY); |
54 | 54 |
variable_del(AddThis::UI_HEADER_COLOR_KEY); |
55 | 55 |
variable_del(AddThis::WIDGET_JS_URL_KEY); |
56 |
variable_del(AddThis::WIDGET_JS_LOAD_TYPE); |
|
56 |
variable_del(AddThis::WIDGET_JS_LOAD_DOMREADY); |
|
57 |
variable_del(AddThis::WIDGET_JS_LOAD_ASYNC); |
|
57 | 58 |
} |
58 | 59 |
|
59 | 60 |
/** |
... | ... | |
62 | 63 |
function addthis_update_7401() { |
63 | 64 |
variable_del('addthis_widget_async'); |
64 | 65 |
} |
66 |
|
|
67 |
/** |
|
68 |
* Remove old addthis_widget_load_type and transform it into new values. |
|
69 |
* |
|
70 |
* Transform variable in settings for domready and async. |
|
71 |
* If value = async set domready TRUE and async TRUE. |
|
72 |
* If value = domready set domready TRUE and async FALSE. |
|
73 |
* If value = include set domready FALSE and async FALSE. |
|
74 |
*/ |
|
75 |
function addthis_update_7402() { |
|
76 |
$load_type = variable_get('addthis_widget_load_type', NULL); |
|
77 |
|
|
78 |
switch ($load_type) { |
|
79 |
case 'async': |
|
80 |
variable_set(AddThis::WIDGET_JS_LOAD_DOMREADY, TRUE); |
|
81 |
variable_set(AddThis::WIDGET_JS_LOAD_ASYNC, TRUE); |
|
82 |
break; |
|
83 |
case 'domready': |
|
84 |
variable_set(AddThis::WIDGET_JS_LOAD_DOMREADY, TRUE); |
|
85 |
variable_set(AddThis::WIDGET_JS_LOAD_ASYNC, FALSE); |
|
86 |
break; |
|
87 |
case 'include': |
|
88 |
variable_set(AddThis::WIDGET_JS_LOAD_DOMREADY, FALSE); |
|
89 |
variable_set(AddThis::WIDGET_JS_LOAD_ASYNC, FALSE); |
|
90 |
break; |
|
91 |
default: |
|
92 |
variable_set(AddThis::WIDGET_JS_LOAD_DOMREADY, TRUE); |
|
93 |
variable_set(AddThis::WIDGET_JS_LOAD_ASYNC, FALSE); |
|
94 |
break; |
|
95 |
} |
|
96 |
|
|
97 |
variable_del('addthis_widget_load_type'); |
|
98 |
} |
drupal7/sites/all/modules/addthis/addthis.js | ||
---|---|---|
1 |
(function ($) { |
|
1 |
/** |
|
2 |
* @file |
|
3 |
* AddThis javascript actions. |
|
4 |
*/ |
|
2 | 5 |
|
6 |
(function ($) { |
|
3 | 7 |
Drupal.behaviors.addthis = { |
8 |
scriptLoaded: false, |
|
9 |
|
|
4 | 10 |
attach: function(context, settings) { |
5 | 11 |
|
6 |
// If addthis settings are provided a display is loaded. |
|
7 |
if (typeof Drupal.settings.addthis != 'undefined') { |
|
8 |
|
|
9 |
if (typeof Drupal.settings.addthis.load_type != 'undefined') { |
|
10 |
if (Drupal.settings.addthis.load_type == 'async') { |
|
11 |
addthis.init(); |
|
12 |
} |
|
13 |
if (Drupal.settings.addthis.load_type == 'domready') { |
|
14 |
$.getScript( |
|
15 |
Drupal.settings.addthis.widget_url, |
|
16 |
function(data, textStatus) {}); |
|
17 |
} |
|
18 |
// Trigger ready on ajax attach. |
|
19 |
if (context != window.document && window.addthis != null) { |
|
20 |
window.addthis.ost = 0; |
|
21 |
window.addthis.ready(); |
|
22 |
} |
|
12 |
// The addthis configuration is not loaded but the settings are passed |
|
13 |
// to do so. |
|
14 |
if (!this.isConfigLoaded() && this.isSettingsLoaded()) { |
|
15 |
// Initialize config. |
|
16 |
this.initConfig(); |
|
17 |
|
|
18 |
// Load widget js. |
|
19 |
if (!this.scriptLoaded) { |
|
20 |
this.loadDomready(); |
|
23 | 21 |
} |
24 | 22 |
} |
23 |
// The addthis configuration is not loaded but no setting are available |
|
24 |
// to load anything. |
|
25 |
else if(!this.isConfigLoaded() && !this.isSettingsLoaded()) { |
|
26 |
// Do nothing |
|
27 |
} |
|
28 |
|
|
29 |
// Trigger ready on ajax attach. |
|
30 |
if (context != window.document) { |
|
31 |
Drupal.behaviors.addthis.ajaxLoad(context, settings); |
|
32 |
} |
|
33 |
|
|
34 |
}, |
|
35 |
|
|
36 |
// Returns if the settings defined by the addthis module are loaded. |
|
37 |
isSettingsLoaded: function () { |
|
38 |
if (typeof Drupal.settings.addthis == 'undefined') { |
|
39 |
return false; |
|
40 |
} |
|
41 |
return true; |
|
42 |
}, |
|
25 | 43 |
|
44 |
// Returns if the configuration variables needed for widget.js are defined. |
|
45 |
isConfigLoaded: function() { |
|
46 |
if (typeof addthis_config == 'undefined' || typeof addthis_share == 'undefined') { |
|
47 |
return false; |
|
48 |
} |
|
49 |
return true; |
|
50 |
}, |
|
51 |
|
|
52 |
initConfig: function () { |
|
53 |
addthis_config = Drupal.settings.addthis.addthis_config; |
|
54 |
addthis_share = Drupal.settings.addthis.addthis_share; |
|
55 |
}, |
|
56 |
|
|
57 |
// Load the js library when the dom is ready. |
|
58 |
loadDomready: function() { |
|
59 |
// If settings asks for loading the script after the dom is loaded, then |
|
60 |
// load the script here. |
|
61 |
if (!this.scriptLoaded && |
|
62 |
this.isConfigLoaded() && |
|
63 |
Drupal.settings.addthis.domready) { |
|
64 |
$.getScript(Drupal.settings.addthis.widget_url, Drupal.behaviors.addthis.scriptReady); |
|
65 |
} |
|
66 |
}, |
|
67 |
|
|
68 |
// Callback for loading the widget.js dynamically. |
|
69 |
scriptReady: function () { |
|
70 |
this.scriptLoaded = true; |
|
71 |
}, |
|
72 |
|
|
73 |
// Called when a ajax request returned. |
|
74 |
ajaxLoad: function(context, settings) { |
|
75 |
if (typeof window.addthis != 'undefined' && |
|
76 |
typeof window.addthis.toolbox == 'function') |
|
77 |
{ |
|
78 |
window.addthis.toolbox('.addthis_toolbox'); |
|
79 |
} |
|
26 | 80 |
} |
81 |
|
|
82 |
}; |
|
83 |
|
|
84 |
// This load the config in time to run any addthis functionality. |
|
85 |
if (Drupal.behaviors.addthis.isConfigLoaded()) { |
|
86 |
addthis_config = Drupal.settings.addthis.addthis_config; |
|
87 |
addthis_share = Drupal.settings.addthis.addthis_share; |
|
27 | 88 |
} |
28 | 89 |
|
90 |
// Document ready in case we want to load AddThis into the dom after every |
|
91 |
// thing is loaded. |
|
92 |
// |
|
93 |
// Is executed once after the attach happened. |
|
94 |
$(document).ready(function() { |
|
95 |
Drupal.behaviors.addthis.loadDomready(); |
|
96 |
}); |
|
97 |
|
|
29 | 98 |
}(jQuery)); |
drupal7/sites/all/modules/addthis/addthis.module | ||
---|---|---|
80 | 80 |
'file' => AddThis::ADMIN_INCLUDE_FILE, |
81 | 81 |
'weight' => 10 |
82 | 82 |
); |
83 |
|
|
83 | 84 |
return $menu_items; |
84 | 85 |
} |
85 | 86 |
|
... | ... | |
142 | 143 |
); |
143 | 144 |
} |
144 | 145 |
|
146 |
/** |
|
147 |
* Implements hook_page_build(). |
|
148 |
*/ |
|
149 |
function addthis_page_build(&$page) { |
|
150 |
// Include the addthis.js as a library on every page. Widget js will be loaded |
|
151 |
// according to the settings. |
|
152 |
$addthis_js_path = drupal_get_path('module', 'addthis') . '/addthis.js'; |
|
153 |
$page['content']['#attached']['js'][$addthis_js_path] = array( |
|
154 |
'type' => 'file', |
|
155 |
'scope' => 'footer', |
|
156 |
); |
|
157 |
|
|
158 |
// Include the widget js when we include on all but admin pages. |
|
159 |
if (!path_is_admin(current_path()) && AddThis::getInstance()->getWidgetJsInclude() == AddThis::WIDGET_JS_INCLUDE_PAGE) { |
|
160 |
$manager = AddThisScriptManager::getInstance(); |
|
161 |
$manager->attachJsToElement($page['content']); |
|
162 |
} |
|
163 |
} |
|
164 |
|
|
145 | 165 |
/** |
146 | 166 |
* Implements hook_preprocess() for theme_addthis. |
147 | 167 |
*/ |
... | ... | |
199 | 219 |
/** |
200 | 220 |
* Create a addthis settings form. |
201 | 221 |
*/ |
202 |
function _addthis_settings_form($form = array(), &$form_state, $display_type = NULL, $display_settings = NULL) { |
|
203 |
// Toggle variables |
|
204 |
$no_js = FALSE; |
|
222 |
function _addthis_settings_form($form = array(), &$form_state = array(), $display_type = NULL, $display_settings = array()) { |
|
205 | 223 |
|
224 |
// Check display setting to be not null. |
|
225 |
if (!isset($display_settings) || (isset($display_settings) && !is_array($display_settings))) { |
|
226 |
$display_settings = array(); |
|
227 |
} |
|
228 |
|
|
229 |
// Toggle variables. |
|
230 |
$no_js = FALSE; |
|
206 | 231 |
|
207 | 232 |
// Default display type if not set in the parameters. |
208 | 233 |
$display_type = (isset($display_type)) ? $display_type : 'addthis_disabled'; |
drupal7/sites/all/modules/addthis/addthis.test | ||
---|---|---|
1 |
<?php |
|
2 |
|
|
3 |
/** |
|
4 |
* @file |
|
5 |
* Tests for the AddThis-module. |
|
6 |
*/ |
|
7 |
|
|
8 |
class AddThisFunctionalityTestCase extends DrupalWebTestCase { |
|
9 |
|
|
10 |
private $user; |
|
11 |
|
|
12 |
public function setUp() { |
|
13 |
parent::setUp(AddThis::MODULE_NAME); |
|
14 |
$this->createAndLoginUser(); |
|
15 |
} |
|
16 |
|
|
17 |
public static function getInfo() { |
|
18 |
return array( |
|
19 |
'name' => 'AddThis: Functionality tests', |
|
20 |
'description' => 'Functionality tests for the AddThis-module.', |
|
21 |
'group' => 'AddThis', |
|
22 |
); |
|
23 |
} |
|
24 |
|
|
25 |
public function testFunctionality() { |
|
26 |
$this->addThisShouldProvideHelp(); |
|
27 |
|
|
28 |
$this->addThisShouldDefineField(); |
|
29 |
|
|
30 |
$this->addThisShouldDefineBlock(); |
|
31 |
|
|
32 |
$this->addThisShouldBeAbleToBeUsedAsField(); |
|
33 |
|
|
34 |
$this->addThisSystemSettingsShouldBeAbleToBeSaved(); |
|
35 |
} |
|
36 |
|
|
37 |
private function addThisShouldProvideHelp() { |
|
38 |
$helpText = module_invoke(AddThis::MODULE_NAME, 'help', 'admin/help#addthis', NULL); |
|
39 |
$this->assertTrue(TestHelper::stringContains($helpText, t('About')), 'AddThis-module should provide help.'); |
|
40 |
} |
|
41 |
|
|
42 |
private function addThisShouldDefineField() { |
|
43 |
$fieldInfo = module_invoke(AddThis::MODULE_NAME, 'field_info'); |
|
44 |
$this->assertTrue(is_array($fieldInfo), t('AddThis-module should define a field.')); |
|
45 |
} |
|
46 |
|
|
47 |
private function addThisShouldDefineBlock() { |
|
48 |
$blockInfo = module_invoke(AddThis::MODULE_NAME, 'block_info'); |
|
49 |
$this->assertTrue(is_array($blockInfo), t('AddThis-module should define a block.')); |
|
50 |
} |
|
51 |
|
|
52 |
private function addThisShouldBeAbleToBeUsedAsField() { |
|
53 |
$edit = array(); |
|
54 |
$label = TestHelper::generateRandomLowercaseString(); |
|
55 |
$edit["fields[_add_new_field][label]"] = $label; |
|
56 |
$edit["fields[_add_new_field][field_name]"] = $label; |
|
57 |
$edit["fields[_add_new_field][type]"] = AddThis::FIELD_TYPE; |
|
58 |
$edit["fields[_add_new_field][widget_type]"] = AddThis::WIDGET_TYPE; |
|
59 |
|
|
60 |
$this->drupalPost('admin/structure/types/manage/article/fields', $edit, t('Save')); |
|
61 |
|
|
62 |
$this->assertText($label, 'AddThis-module should be able to be added as a field.'); |
|
63 |
|
|
64 |
$this->addThisShouldNotHaveConfigurableFieldLevelSettings($label); |
|
65 |
|
|
66 |
$this->drupalGet('admin/structure/types/manage/article/display'); |
|
67 |
} |
|
68 |
|
|
69 |
private function addThisShouldNotHaveConfigurableFieldLevelSettings($label) { |
|
70 |
$this->assertText(t("@name has no field settings.", array('@name' => $label)), |
|
71 |
'AddThis-module should not have configurable field level settings.'); |
|
72 |
} |
|
73 |
|
|
74 |
private function addThisSystemSettingsShouldBeAbleToBeSaved() { |
|
75 |
$edit_basic = array(); |
|
76 |
|
|
77 |
// Basic settings |
|
78 |
$profileId = TestHelper::generateRandomLowercaseString(); |
|
79 |
$edit_basic[AddThis::PROFILE_ID_KEY] = $profileId; |
|
80 |
|
|
81 |
$uiDelay = 400; |
|
82 |
$edit_basic[AddThis::UI_DELAY_KEY] = $uiDelay; |
|
83 |
|
|
84 |
$uiHeaderBackgroundColor = '#000000'; |
|
85 |
$edit_basic[AddThis::UI_HEADER_BACKGROUND_COLOR_KEY] = $uiHeaderBackgroundColor; |
|
86 |
|
|
87 |
$uiHeaderColor = '#ffffff'; |
|
88 |
$edit_basic[AddThis::UI_HEADER_COLOR_KEY] = $uiHeaderColor; |
|
89 |
|
|
90 |
$coBrand = TestHelper::generateRandomLowercaseString(); |
|
91 |
$edit_basic[AddThis::CO_BRAND_KEY] = $coBrand; |
|
92 |
|
|
93 |
$edit_basic[AddThis::COMPLIANT_508_KEY] = TRUE; |
|
94 |
|
|
95 |
$edit_basic[AddThis::CLICKBACK_TRACKING_ENABLED_KEY] = TRUE; |
|
96 |
|
|
97 |
// Can only be tested with Google Analytics module installed. |
|
98 |
//$edit_basic[AddThis::GOOGLE_ANALYTICS_TRACKING_ENABLED_KEY] = TRUE; |
|
99 |
|
|
100 |
//$edit_basic[AddThis::GOOGLE_ANALYTICS_SOCIAL_TRACKING_ENABLED_KEY] = TRUE; |
|
101 |
|
|
102 |
$edit_basic[AddThis::ADDRESSBOOK_ENABLED_KEY] = TRUE; |
|
103 |
|
|
104 |
$edit_basic[AddThis::CLICK_TO_OPEN_COMPACT_MENU_ENABLED_KEY] = TRUE; |
|
105 |
|
|
106 |
$edit_basic[AddThis::OPEN_WINDOWS_ENABLED_KEY] = TRUE; |
|
107 |
|
|
108 |
$edit_basic[AddThis::STANDARD_CSS_ENABLED_KEY] = TRUE; |
|
109 |
|
|
110 |
$serviceName = '2linkme'; |
|
111 |
$edit_basic["addthis_enabled_services[$serviceName]"] = $serviceName; |
|
112 |
|
|
113 |
$this->drupalPost('admin/config/user-interface/addthis', $edit_basic, t('Save configuration')); |
|
114 |
|
|
115 |
$this->assertText(t('The configuration options have been saved.'), 'AddThis system settings should be able to be saved.'); |
|
116 |
|
|
117 |
$this->addThisProfileIdShouldBeAbleToBeSaved($profileId); |
|
118 |
|
|
119 |
$this->addThisUiDelayShouldBeAbleToBeSaved($uiDelay); |
|
120 |
|
|
121 |
$this->addThisUiHeaderBackgroundColorShouldBeAbleToBeSaved($uiHeaderBackgroundColor); |
|
122 |
|
|
123 |
$this->addThisUiHeaderColorShouldBeAbleToBeSaved($uiHeaderColor); |
|
124 |
|
|
125 |
$this->addThisCoBrandShouldBeAbleToBeSaved($coBrand); |
|
126 |
|
|
127 |
$this->addThis508CompliantSettingShouldBeAbleToBeSaved(); |
|
128 |
|
|
129 |
$this->addThisClickbackTrackingEnabledSettingShouldBeAbleToBeSaved(); |
|
130 |
|
|
131 |
// Can only be tested with Google Analytics module installed. |
|
132 |
//$this->addThisGoogleAnalyticsTrackingEnabledSettingShouldBeAbleToBeSaved(); |
|
133 |
|
|
134 |
//$this->addThisGoogleAnalyticsSocialTrackingEnabledSettingShouldBeAbleToBeSaved(); |
|
135 |
|
|
136 |
$this->addThisClickToOpenCompactMenuEnabledSettingShouldBeAbleToBeSaved(); |
|
137 |
|
|
138 |
$this->addThisOpenWindowsEnabledSettingShouldBeAbleToBeSaved(); |
|
139 |
|
|
140 |
$this->addThisStandardCssEnabledSettingShouldBeAbleToBeSaved(); |
|
141 |
|
|
142 |
$this->addThisEnabledServicesShouldBeAbleToBeSaved($serviceName); |
|
143 |
|
|
144 |
// Advanced configuration |
|
145 |
$edit_basic = array(); |
|
146 |
|
|
147 |
$servicesCssUrl = AddThis::DEFAULT_SERVICES_CSS_URL; |
|
148 |
$edit_basic[AddThis::SERVICES_CSS_URL_KEY] = $servicesCssUrl; |
|
149 |
|
|
150 |
$servicesJsonUrl = AddThis::DEFAULT_SERVICES_JSON_URL; |
|
151 |
$edit_basic[AddThis::SERVICES_JSON_URL_KEY] = $servicesJsonUrl; |
|
152 |
|
|
153 |
$widgetJsUrl = AddThis::DEFAULT_WIDGET_JS_URL; |
|
154 |
$edit_basic[AddThis::WIDGET_JS_URL_KEY] = $widgetJsUrl; |
|
155 |
|
|
156 |
$edit_basic[AddThis::CUSTOM_CONFIGURATION_CODE_ENABLED_KEY] = TRUE; |
|
157 |
|
|
158 |
$customConfigurationCode = TestHelper::generateRandomLowercaseString(); |
|
159 |
$edit_basic[AddThis::CUSTOM_CONFIGURATION_CODE_KEY] = $customConfigurationCode; |
|
160 |
|
|
161 |
$this->drupalPost('admin/config/user-interface/addthis/advanced', $edit_basic, t('Save configuration')); |
|
162 |
|
|
163 |
$this->addThisServicesCssUrlShouldBeAbleToBeSaved($servicesCssUrl); |
|
164 |
|
|
165 |
$this->addThisServicesJsonUrlShouldBeAbleToBeSaved($servicesJsonUrl); |
|
166 |
|
|
167 |
$this->addThisWidgetJsUrlShouldBeAbleToBeSaved($widgetJsUrl); |
|
168 |
|
|
169 |
$this->addThisCustomConfigurationCodeEnabledSettingShouldBeAbleToBeSaved(); |
|
170 |
} |
|
171 |
|
|
172 |
private function addThisProfileIdShouldBeAbleToBeSaved($profileId) { |
|
173 |
$this->assertFieldByName(AddThis::PROFILE_ID_KEY, $profileId, |
|
174 |
'AddThis profile ID should be able to be saved.'); |
|
175 |
} |
|
176 |
|
|
177 |
private function addThisServicesCssUrlShouldBeAbleToBeSaved($servicesCssUrl) { |
|
178 |
$this->assertFieldByName(AddThis::SERVICES_CSS_URL_KEY, $servicesCssUrl, |
|
179 |
'AddThis services stylesheet URL should be able to be saved.'); |
|
180 |
} |
|
181 |
|
|
182 |
private function addThisServicesJsonUrlShouldBeAbleToBeSaved($servicesJsonUrl) { |
|
183 |
$this->assertFieldByName(AddThis::SERVICES_JSON_URL_KEY, $servicesJsonUrl, |
|
184 |
'AddThis services json URL should be able to be saved.'); |
|
185 |
} |
|
186 |
|
|
187 |
private function addThisWidgetJsUrlShouldBeAbleToBeSaved($widgetJsUrl) { |
|
188 |
$this->assertFieldByName(AddThis::WIDGET_JS_URL_KEY, $widgetJsUrl, |
|
189 |
'AddThis javascript widget URL should be able to be saved.'); |
|
190 |
} |
|
191 |
|
|
192 |
private function addThis508CompliantSettingShouldBeAbleToBeSaved() { |
|
193 |
$this->assertFieldChecked('edit-addthis-508-compliant', |
|
194 |
'AddThis 508 compliant setting should be able to be saved.'); |
|
195 |
} |
|
196 |
|
|
197 |
private function addThisClickbackTrackingEnabledSettingShouldBeAbleToBeSaved() { |
|
198 |
$this->assertFieldChecked('edit-addthis-clickback-tracking-enabled', |
|
199 |
'AddThis clickback tracking enabled setting should be able to be saved.'); |
|
200 |
} |
|
201 |
|
|
202 |
private function addThisGoogleAnalyticsTrackingEnabledSettingShouldBeAbleToBeSaved() { |
|
203 |
$this->assertFieldChecked('edit-addthis-google-analytics-tracking-enabled', |
|
204 |
'AddThis Google Analytics tracking enabled setting should be able to be saved.'); |
|
205 |
} |
|
206 |
|
|
207 |
private function addThisGoogleAnalyticsSocialTrackingEnabledSettingShouldBeAbleToBeSaved() { |
|
208 |
$this->assertFieldChecked('edit-addthis-google-analytics-tracking-enabled', |
|
209 |
'AddThis Google Analytics social tracking enabled setting should be able to be saved.'); |
|
210 |
} |
|
211 |
|
|
212 |
private function addThisClickToOpenCompactMenuEnabledSettingShouldBeAbleToBeSaved() { |
|
213 |
$this->assertFieldChecked('edit-addthis-click-to-open-compact-menu-enabled', |
|
214 |
'AddThis click to open compact menu setting should be able to be saved.'); |
|
215 |
} |
|
216 |
|
|
217 |
private function addThisOpenWindowsEnabledSettingShouldBeAbleToBeSaved() { |
|
218 |
$this->assertFieldChecked('edit-addthis-open-windows-enabled', |
|
219 |
'AddThis open windows setting should be able to be saved.'); |
|
220 |
} |
|
221 |
|
|
222 |
private function addThisStandardCssEnabledSettingShouldBeAbleToBeSaved() { |
|
223 |
$this->assertFieldChecked('edit-addthis-open-windows-enabled', |
|
224 |
'AddThis open windows setting should be able to be saved.'); |
|
225 |
} |
|
226 |
|
|
227 |
private function addThisFacebookLikeEnabledSettingShouldBeAbleToBeSaved() { |
|
228 |
$this->assertFieldChecked('edit-addthis-facebook-like-enabled', |
|
229 |
'AddThis Facebook Like enabled setting should be able to be saved.'); |
|
230 |
} |
|
231 |
|
|
232 |
private function addThisAddressbookEnabledSettingShouldBeAbleToBeSaved() { |
|
233 |
$this->assertFieldChecked('edit-addthis-addressbook-enabled', |
|
234 |
'AddThis addressbook enabled setting should be able to be saved.'); |
|
235 |
} |
|
236 |
|
|
237 |
private function addThisCustomConfigurationCodeEnabledSettingShouldBeAbleToBeSaved() { |
|
238 |
$this->assertFieldChecked('edit-addthis-custom-configuration-code-enabled', |
|
239 |
'AddThis custom configuration code enabled setting should be able to be saved.'); |
|
240 |
} |
|
241 |
|
|
242 |
private function addThisCustomConfigurationCodeShouldBeAbleToBeSaved($customConfigurationCode) { |
|
243 |
$this->assertFieldByName(AddThis::CUSTOM_CONFIGURATION_CODE_KEY, $customConfigurationCode, |
|
244 |
'AddThis custom configuration code should be able to be saved.'); |
|
245 |
} |
|
246 |
|
|
247 |
private function addThisUiHeaderColorShouldBeAbleToBeSaved($uiHeaderColor) { |
|
248 |
$this->assertFieldByName(AddThis::UI_HEADER_COLOR_KEY, $uiHeaderColor, |
|
249 |
'AddThis UI header color should be able to be saved.'); |
|
250 |
} |
|
251 |
|
|
252 |
private function addThisUiDelayShouldBeAbleToBeSaved($uiDelay) { |
|
253 |
$this->assertFieldByName(AddThis::UI_DELAY_KEY, $uiDelay, |
|
254 |
'AddThis UI delay should be able to be saved.'); |
|
255 |
} |
|
256 |
|
|
257 |
private function addThisUiHeaderBackgroundColorShouldBeAbleToBeSaved($uiHeaderBackgroundColor) { |
|
258 |
$this->assertFieldByName(AddThis::UI_HEADER_BACKGROUND_COLOR_KEY, $uiHeaderBackgroundColor, |
|
259 |
'AddThis UI header background color should be able to be saved.'); |
|
260 |
} |
|
261 |
|
|
262 |
private function addThisCoBrandShouldBeAbleToBeSaved($coBrand) { |
|
263 |
$this->assertFieldByName(AddThis::CO_BRAND_KEY, $coBrand, |
|
264 |
'AddThis co-brand should be able to be saved.'); |
|
265 |
} |
|
266 |
|
|
267 |
private function addThisEnabledServicesShouldBeAbleToBeSaved($serviceName) { |
|
268 |
$this->assertFieldChecked('edit-addthis-enabled-services-' . $serviceName, |
|
269 |
'AddThis enabled services should be able to be saved.'); |
|
270 |
} |
|
271 |
|
|
272 |
private function createAndLoginUser() { |
|
273 |
$this->user = $this->createAdminUser(); |
|
274 |
$this->drupalLogin($this->user); |
|
275 |
} |
|
276 |
|
|
277 |
private function createAdminUser() { |
|
278 |
return $this->drupalCreateUser( |
|
279 |
array( |
|
280 |
AddThis::PERMISSION_ADMINISTER_ADDTHIS, |
|
281 |
AddThis::PERMISSION_ADMINISTER_ADVANCED_ADDTHIS, |
|
282 |
'administer blocks', |
|
283 |
'administer content types', |
|
284 |
'administer nodes' |
|
285 |
) |
|
286 |
); |
|
287 |
} |
|
288 |
} |
|
289 |
|
|
290 |
class AddThisPermissionsTestCase extends DrupalWebTestCase { |
|
291 |
|
|
292 |
public function setUp() { |
|
293 |
parent::setUp(AddThis::MODULE_NAME); |
|
294 |
} |
|
295 |
|
|
296 |
public static function getInfo() { |
|
297 |
return array( |
|
298 |
'name' => 'AddThis: Permission tests', |
|
299 |
'description' => 'Permission tests for the AddThis-module.', |
|
300 |
'group' => 'AddThis', |
|
301 |
); |
|
302 |
} |
|
303 |
|
|
304 |
public function testUserWithoutAdministerAddThisPermissionShouldNotBeAllowedToAccessAddThisSystemSettings() { |
|
305 |
$this->drupalLogin($this->createAdminUserWithoutAddThisAdministrationPermission()); |
|
306 |
$this->drupalGet('admin/config/system/addthis'); |
|
307 |
$this->assertRaw(t('Access denied'), |
|
308 |
'A user without administer addthis permission should not be able to access AddThis system settings.'); |
|
309 |
} |
|
310 |
|
|
311 |
public function testUserWithoutAdministerAdvancedAddThisPermissionShouldNotBeAllowedToAccessAdvancedAddThisSystemSettings() { |
|
312 |
$this->drupalLogin($this->createAdminUserWithoutAdvancedAddThisAdministrationPermission()); |
|
313 |
$this->drupalGet('admin/config/system/addthis'); |
|
314 |
$this->assertNoRaw(t('Advanced settings'), |
|
315 |
'A user without administer advanced addthis permission should not be able to access advanced AddThis system settings.'); |
|
316 |
} |
|
317 |
|
|
318 |
private function createAdminUserWithoutAddThisAdministrationPermission() { |
|
319 |
return $this->drupalCreateUser(array('administer content types')); |
|
320 |
} |
|
321 |
|
|
322 |
private function createAdminUserWithoutAdvancedAddThisAdministrationPermission() { |
|
323 |
return $this->drupalCreateUser(array('administer content types', AddThis::PERMISSION_ADMINISTER_ADDTHIS)); |
|
324 |
} |
|
325 |
} |
|
326 |
|
|
327 |
class TestHelper { |
|
328 |
|
|
329 |
public static function stringContains($string, $contains) { |
|
330 |
return strpos($string, $contains) !== FALSE; |
|
331 |
} |
|
332 |
|
|
333 |
public static function generateRandomLowercaseString() { |
|
334 |
return drupal_strtolower(DrupalWebTestCase::randomName()); |
|
335 |
} |
|
336 |
} |
drupal7/sites/all/modules/addthis/addthis_displays/addthis_displays.addthis.inc | ||
---|---|---|
32 | 32 |
); |
33 | 33 |
$element['#attributes'] += $addthis->getAddThisAttributesMarkup($options); |
34 | 34 |
|
35 |
// Add the widget script. |
|
36 |
$script_manager = AddThisScriptManager::getInstance(); |
|
37 |
$script_manager->attachJsToElement($element); |
|
38 |
|
|
35 | 39 |
$services = trim($options['#display']['settings']['share_services']); |
36 | 40 |
$services = str_replace(' ', '', $services); |
37 | 41 |
$services = explode(',', $services); |
... | ... | |
52 | 56 |
'#addthis_service' => $service, |
53 | 57 |
); |
54 | 58 |
|
59 |
// Add individual counters. |
|
60 |
if (strpos($service, 'counter_') === 0) { |
|
61 |
$items[$service]['#attributes']['class'] = array("addthis_$service"); |
|
62 |
} |
|
63 |
|
|
55 | 64 |
// Basic implementations of bubble counter orientation. |
56 | 65 |
// @todo Figure all the bubbles out and add them. |
57 |
// Still missing: tweetme, hyves and stubleupon. |
|
66 |
// Still missing: tweetme, hyves and stubleupon, google_plusone_badge.
|
|
58 | 67 |
// |
59 |
// @todo Fix a way to use addthis_bubble_style. |
|
60 |
// There is a conflict now with using the class addthis_button_[service]. |
|
61 |
// You can't add this bubble style now. |
|
62 | 68 |
$orientation = ($options['#display']['settings']['counter_orientation'] == 'horizontal' ? TRUE : FALSE); |
63 | 69 |
switch ($service) { |
70 |
case 'linkedin_counter': |
|
71 |
$items[$service]['#attributes'] += array( |
|
72 |
'li:counter' => ($orientation ? '' : 'top'), |
|
73 |
); |
|
74 |
break; |
|
64 | 75 |
case 'facebook_like': |
65 | 76 |
$items[$service]['#attributes'] += array( |
66 | 77 |
'fb:like:layout' => ($orientation ? 'button_count' : 'box_count') |
67 | 78 |
); |
68 | 79 |
break; |
80 |
case 'facebook_share': |
|
81 |
$items[$service]['#attributes'] += array( |
|
82 |
'fb:share:layout' => ($orientation ? 'button_count' : 'box_count') |
|
83 |
); |
|
84 |
break; |
|
69 | 85 |
case 'google_plusone': |
70 | 86 |
$items[$service]['#attributes'] += array( |
71 | 87 |
'g:plusone:size' => ($orientation ? 'standard' : 'tall') |
... | ... | |
77 | 93 |
'tw:via' => AddThis::getInstance()->getTwitterVia(), |
78 | 94 |
); |
79 | 95 |
break; |
96 |
case 'bubble_style': |
|
97 |
$items[$service]['#attributes']['class'] = array( |
|
98 |
'addthis_counter', 'addthis_bubble_style' |
|
99 |
); |
|
100 |
break; |
|
101 |
case 'pill_style': |
|
102 |
$items[$service]['#attributes']['class'] = array( |
|
103 |
'addthis_counter', 'addthis_pill_style' |
|
104 |
); |
|
105 |
break; |
|
80 | 106 |
} |
81 | 107 |
} |
82 | 108 |
$element += $items; |
... | ... | |
111 | 137 |
); |
112 | 138 |
$element['#attributes'] += $addthis->getAddThisAttributesMarkup($options); |
113 | 139 |
|
140 |
// Add the widget script. |
|
141 |
$script_manager = AddThisScriptManager::getInstance(); |
|
142 |
$script_manager->attachJsToElement($element); |
|
143 |
|
|
114 | 144 |
// Create img button. |
115 | 145 |
$image = array( |
116 | 146 |
'#theme' => 'addthis_element', |
drupal7/sites/all/modules/addthis/addthis_displays/addthis_displays.field.inc | ||
---|---|---|
49 | 49 |
'#default_value' => $settings['share_services'], |
50 | 50 |
'#required' => TRUE, |
51 | 51 |
'#element_validate' => array('_addthis_display_element_validate_services'), |
52 |
'#description' => t('Specify the names of the sharing services and seperate them with a , (comma). <a href="http://www.addthis.com/services/list">The names on this list are valid.</a>'), |
|
52 |
'#description' => |
|
53 |
t('Specify the names of the sharing services and seperate them with a , (comma). <a href="http://www.addthis.com/services/list" target="_blank">The names on this list are valid.</a>') . |
|
54 |
t('Elements that are available but not ont the services list are (!services).', |
|
55 |
array('!services' => 'bubble_style, pill_style, tweet, facebook_send, twitter_follow_native, google_plusone, stumbleupon_badge, counter_* (several supported services), linkedin_counter') |
|
56 |
), |
|
53 | 57 |
); |
54 | 58 |
$element['buttons_size'] = array( |
55 | 59 |
'#title' => t('Buttons size'), |
... | ... | |
110 | 114 |
$services = trim($element['#value']); |
111 | 115 |
$services = str_replace(' ', '', $services); |
112 | 116 |
|
113 |
if (!preg_match('/^[a-z\_\,]+$/', $services)) { |
|
117 |
if (!preg_match('/^[a-z\_\,0-9]+$/', $services)) {
|
|
114 | 118 |
$bad = TRUE; |
115 | 119 |
} |
116 | 120 |
// @todo Validate the service names against AddThis.com. Give a notice when there are bad names. |
drupal7/sites/all/modules/addthis/addthis_displays/addthis_displays.info | ||
---|---|---|
5 | 5 |
dependencies[] = addthis |
6 | 6 |
files[] = addthis_displays.field.inc |
7 | 7 |
|
8 |
; Information added by Drupal.org packaging script on 2014-01-22
|
|
9 |
version = "7.x-4.0-alpha4"
|
|
8 |
; Information added by Drupal.org packaging script on 2015-06-15
|
|
9 |
version = "7.x-4.0-alpha6"
|
|
10 | 10 |
core = "7.x" |
11 | 11 |
project = "addthis" |
12 |
datestamp = "1390384409"
|
|
12 |
datestamp = "1434368594"
|
|
13 | 13 |
|
drupal7/sites/all/modules/addthis/addthis_test/addthis_test.info | ||
---|---|---|
1 |
name = AddThis tests |
|
2 |
description = Module for testing AddThis functionality. |
|
3 |
core = 7.x |
|
4 |
hidden = true |
|
5 |
|
|
6 |
dependencies[] = addthis |
|
7 |
dependencies[] = addthis_displays |
|
8 |
|
|
9 |
; Information added by Drupal.org packaging script on 2015-06-15 |
|
10 |
version = "7.x-4.0-alpha6" |
|
11 |
core = "7.x" |
|
12 |
project = "addthis" |
|
13 |
datestamp = "1434368594" |
|
14 |
|
drupal7/sites/all/modules/addthis/addthis_test/addthis_test.module | ||
---|---|---|
1 |
<?php |
|
2 |
/** |
|
3 |
* Implements hook_page_build(). |
|
4 |
*/ |
|
5 |
function addthis_test_page_build(&$page) { |
|
6 |
|
|
7 |
// See AddThisTestHelper.php.page.inc for more info. |
|
8 |
if (current_path() == 'addthis/test/2') { |
|
9 |
$manager = AddThisScriptManager::getInstance(); |
|
10 |
$manager->attachJsToElement($page['content']); |
|
11 |
} |
|
12 |
} |
|
13 |
|
|
14 |
/** |
|
15 |
* Implements hook_menu(). |
|
16 |
*/ |
|
17 |
function addthis_test_menu() { |
|
18 |
// Test pages. |
|
19 |
// Pages used in the test cases. |
|
20 |
$menu_items['addthis/test/1'] = array( |
|
21 |
'title' => 'Test no Javascript load', |
|
22 |
'type' => MENU_CALLBACK, |
|
23 |
'page callback' => 'addthis_test_no_js', |
|
24 |
'access arguments' => array(AddThis::PERMISSION_ADMINISTER_ADDTHIS), |
|
25 |
'file' => 'includes/addthis.test_pages.inc' |
|
26 |
); |
|
27 |
$menu_items['addthis/test/2'] = array( |
|
28 |
'title' => 'Test Javascript load on preprocess', |
|
29 |
'type' => MENU_CALLBACK, |
|
30 |
'page callback' => 'addthis_test_with_js', |
|
31 |
'access arguments' => array(AddThis::PERMISSION_ADMINISTER_ADDTHIS), |
|
32 |
'file' => 'includes/addthis.test_pages.inc' |
|
33 |
); |
|
34 |
return $menu_items; |
|
35 |
} |
drupal7/sites/all/modules/addthis/addthis_test/includes/addthis.test_pages.inc | ||
---|---|---|
1 |
<?php |
|
2 |
/** |
|
3 |
* @file |
|
4 |
* Callbacks for test pages that include AddThis functionality. |
|
5 |
*/ |
|
6 |
|
|
7 |
/** |
|
8 |
* Page callback to test a page load without any js loaded. |
|
9 |
* |
|
10 |
* @return array |
|
11 |
* Render array for a page. |
|
12 |
*/ |
|
13 |
function addthis_test_no_js() { |
|
14 |
$content = array(); |
|
15 |
|
|
16 |
$content['explanation'] = array( |
|
17 |
'#markup' => 'No widget js is loaded on this page. Unless specified in the settings.', |
|
18 |
); |
|
19 |
|
|
20 |
return $content; |
|
21 |
} |
|
22 |
|
|
23 |
/** |
|
24 |
* Page callback to test a page load with js loaded. |
|
25 |
* |
|
26 |
* @return array |
|
27 |
* Render array for this page. |
|
28 |
*/ |
|
29 |
function addthis_test_with_js() { |
|
30 |
$content = array(); |
|
31 |
|
|
32 |
$content['explanation'] = array( |
|
33 |
'#markup' => 'Widget js is loaded on this page through hook_page_build().<br> |
|
34 |
<!-- Go to www.addthis.com/dashboard to customize your tools --> |
|
35 |
<div class="addthis_sharing_toolbox"></div>', |
|
36 |
); |
|
37 |
|
|
38 |
return $content; |
|
39 |
} |
|
40 |
|
drupal7/sites/all/modules/addthis/classes/AddThis.php | ||
---|---|---|
34 | 34 |
const CUSTOM_CONFIGURATION_CODE_ENABLED_KEY = 'addthis_custom_configuration_code_enabled'; |
35 | 35 |
const CUSTOM_CONFIGURATION_CODE_KEY = 'addthis_custom_configuration_code'; |
36 | 36 |
const ENABLED_SERVICES_KEY = 'addthis_enabled_services'; |
37 |
const EXCLUDED_SERVICES_KEY = 'addthis_excluded_services'; |
|
37 | 38 |
const GOOGLE_ANALYTICS_TRACKING_ENABLED_KEY = 'addthis_google_analytics_tracking_enabled'; |
38 | 39 |
const GOOGLE_ANALYTICS_SOCIAL_TRACKING_ENABLED_KEY = 'addthis_google_analytics_social_tracking_enabled'; |
39 | 40 |
const FACEBOOK_LIKE_COUNT_SUPPORT_ENABLED = 'addthis_facebook_like_count_support_enabled'; |
... | ... | |
46 | 47 |
const UI_HEADER_BACKGROUND_COLOR_KEY = 'addthis_ui_header_background_color'; |
47 | 48 |
const UI_HEADER_COLOR_KEY = 'addthis_ui_header_color'; |
48 | 49 |
const WIDGET_JS_URL_KEY = 'addthis_widget_js_url'; |
49 |
const WIDGET_JS_LOAD_TYPE = 'addthis_widget_load_type'; |
|
50 |
const WIDGET_JS_LOAD_DOMREADY = 'addthis_widget_load_domready'; |
|
51 |
const WIDGET_JS_LOAD_ASYNC = 'addthis_widget_load_async'; |
|
52 |
const WIDGET_JS_INCLUDE = 'addthis_widget_include'; |
|
50 | 53 |
|
51 | 54 |
// Twitter. |
52 | 55 |
const TWITTER_VIA_KEY = 'addthis_twitter_via'; |
... | ... | |
59 | 62 |
const DEFAULT_SERVICES_CSS_URL = 'http://cache.addthiscdn.com/icons/v1/sprites/services.css'; |
60 | 63 |
const DEFAULT_SERVICES_JSON_URL = 'http://cache.addthiscdn.com/services/v1/sharing.en.json'; |
61 | 64 |
const DEFAULT_WIDGET_JS_URL = 'http://s7.addthis.com/js/300/addthis_widget.js'; |
62 |
const DEFAULT_WIDGET_JS_LOAD_TYPE = 'async'; |
|
65 |
const DEFAULT_WIDGET_JS_LOAD_DOMREADY = TRUE; |
|
66 |
const DEFAULT_WIDGET_JS_LOAD_ASYNC = FALSE; |
|
67 |
|
|
68 |
// Type of inclusion. |
|
69 |
// 0 = don't include, 1 = pages no admin, 2 = on usages only. |
|
70 |
const DEFAULT_WIDGET_JS_INCLUDE = 2; |
|
71 |
const WIDGET_JS_INCLUDE_NONE = 0; |
|
72 |
const WIDGET_JS_INCLUDE_PAGE = 1; |
|
73 |
const WIDGET_JS_INCLUDE_USAGE = 2; |
|
74 |
|
|
63 | 75 |
|
64 | 76 |
// Internal resources. |
65 | 77 |
const ADMIN_CSS_FILE = 'addthis.admin.css'; |
... | ... | |
84 | 96 |
* Instance of AddThis. |
85 | 97 |
*/ |
86 | 98 |
public static function getInstance() { |
87 |
module_load_include('php', 'addthis', 'classes/AddThisJson'); |
|
88 |
module_load_include('php', 'addthis', 'classes/AddThisWidgetJs'); |
|
89 | 99 |
|
90 | 100 |
if (!isset(self::$instance)) { |
91 | 101 |
$add_this = new AddThis(); |
... | ... | |
134 | 144 |
return array(); |
135 | 145 |
} |
136 | 146 |
|
137 |
// Load resources. |
|
138 |
self::$instance->includeWidgetJs(); |
|
139 |
self::$instance->addConfigurationOptionsJs(); |
|
140 |
|
|
141 | 147 |
// The display type exists. Now get it and get the markup. |
142 | 148 |
$display_information = $formatters[$display]; |
143 | 149 |
|
... | ... | |
206 | 212 |
return $rows; |
207 | 213 |
} |
208 | 214 |
|
209 |
/** |
|
210 |
* Add the AddThis Widget JavaScript to the page. |
|
211 |
*/ |
|
212 |
public function addWidgetJs() { |
|
213 |
$widgetjs = new AddThisWidgetJs(self::getWidgetUrl()); |
|
214 |
$widgetjs->addAttribute('pubid', $this->getProfileId()); |
|
215 |
|
|
216 |
if (self::getWidgetJsLoadType() != 'include') { |
|
217 |
$widgetjs->addAttribute(self::getWidgetJsLoadType(), '1'); |
|
218 |
} |
|
219 |
|
|
220 |
$url = $widgetjs->getFullUrl(); |
|
221 |
|
|
222 |
switch (self::getWidgetJsLoadType()) { |
|
223 |
|
|
224 |
// Load as DOM is ready. |
|
225 |
case 'domready': |
|
226 |
drupal_add_js( |
|
227 |
array( |
|
228 |
'addthis' => array( |
|
229 |
'widget_url' => $url, |
|
230 |
'load_type' => self::getWidgetJsLoadType(), |
|
231 |
), |
|
232 |
), |
|
233 |
'setting' |
|
234 |
); |
|
235 |
break; |
|
236 |
|
|
237 |
// Load as async. |
|
238 |
case 'async': |
|
239 |
drupal_add_js( |
|
240 |
array( |
|
241 |
'addthis' => array( |
|
242 |
'load_type' => self::getWidgetJsLoadType(), |
|
243 |
), |
|
244 |
), |
|
245 |
'setting' |
|
246 |
); |
|
247 |
|
|
248 |
drupal_add_js( |
|
249 |
$url, |
|
250 |
array( |
|
251 |
'type' => 'external', |
|
252 |
'scope' => 'footer', |
|
253 |
) |
|
254 |
); |
|
255 |
break; |
|
256 |
|
|
257 |
// Load as include in the page. |
|
258 |
default: |
|
259 |
drupal_add_js( |
|
260 |
$url, |
|
261 |
array( |
|
262 |
'type' => 'external', |
|
263 |
'scope' => 'footer', |
|
264 |
) |
|
265 |
); |
|
266 |
break; |
|
267 |
} |
|
268 |
|
|
269 |
// Add local internal behaviours. |
|
270 |
drupal_add_js( |
|
271 |
drupal_get_path('module', 'addthis') . '/addthis.js', |
|
272 |
array( |
|
273 |
'type' => 'file', |
|
274 |
'scope' => 'footer', |
|
275 |
) |
|
276 |
); |
|
277 |
} |
|
278 |
|
|
279 |
/** |
|
280 |
* Load function for widget information. |
|
281 |
* |
|
282 |
* Loading widget information only once. |
|
283 |
*/ |
|
284 |
public function includeWidgetJs() { |
|
285 |
static $loaded; |
|
286 |
|
|
287 |
if (!isset($loaded)) { |
|
288 |
$loaded = TRUE; |
|
289 |
$this->addWidgetJs(); |
|
290 |
|
|
291 |
return TRUE; |
|
292 |
} |
|
293 |
return FALSE; |
|
294 |
} |
|
295 |
|
|
296 |
public function addConfigurationOptionsJs() { |
|
297 |
if ($this->isCustomConfigurationCodeEnabled()) { |
|
298 |
$configurationOptionsJavascript = $this->getCustomConfigurationCode(); |
|
299 |
} |
|
300 |
else { |
|
301 |
$enabledServices = $this->getServiceNamesAsCommaSeparatedString() . 'more'; |
|
302 |
|
|
303 |
global $language; |
|
304 |
$configuration = array( |
|
305 |
'pubid' => $this->getProfileId(), |
|
306 |
'services_compact' => $enabledServices, |
|
307 |
'data_track_clickback' => $this->isClickbackTrackingEnabled(), |
|
308 |
'ui_508_compliant' => $this->get508Compliant(), |
|
309 |
'ui_click' => $this->isClickToOpenCompactMenuEnabled(), |
|
310 |
'ui_cobrand' => $this->getCoBrand(), |
|
311 |
'ui_delay' => $this->getUiDelay(), |
|
312 |
'ui_header_background' => $this->getUiHeaderBackgroundColor(), |
|
313 |
'ui_header_color' => $this->getUiHeaderColor(), |
|
314 |
'ui_open_windows' => $this->isOpenWindowsEnabled(), |
|
315 |
'ui_use_css' => $this->isStandardCssEnabled(), |
|
316 |
'ui_use_addressbook' => $this->isAddressbookEnabled(), |
|
317 |
'ui_language' => $language->language, |
|
318 |
); |
|
319 |
if (module_exists('googleanalytics')) { |
|
320 |
if ($this->isGoogleAnalyticsTrackingEnabled()) { |
|
321 |
$configuration['data_ga_property'] = variable_get('googleanalytics_account', ''); |
|
322 |
$configuration['data_ga_social'] = $this->isGoogleAnalyticsSocialTrackingEnabled(); |
|
323 |
} |
|
324 |
} |
|
325 |
$configuration['templates']['twitter'] = $this->getTwitterTemplate(); |
|
326 |
drupal_alter('addthis_configuration', $configuration); |
|
327 |
|
|
328 |
$templates = array('templates' => $configuration['templates']); |
|
329 |
unset($configuration['templates']); |
|
330 |
$configurationOptionsJavascript = 'var addthis_config = ' . drupal_json_encode($configuration) . "\n"; |
|
331 |
$configurationOptionsJavascript .= 'var addthis_share = ' . drupal_json_encode($templates); |
|
332 |
} |
|
333 |
drupal_add_js( |
|
334 |
$configurationOptionsJavascript, |
|
335 |
array( |
|
336 |
'type' => 'inline', |
|
337 |
'scope' => 'footer', |
|
338 |
'every_page' => TRUE, |
|
339 |
) |
|
340 |
); |
|
341 |
} |
|
342 |
|
|
343 | 215 |
public function getAddThisAttributesMarkup($options) { |
344 | 216 |
if (isset($options)) { |
345 | 217 |
$attributes = array(); |
... | ... | |
390 | 262 |
return variable_get(self::ENABLED_SERVICES_KEY, array()); |
391 | 263 |
} |
392 | 264 |
|
265 |
public function getExcludedServices() { |
|
266 |
return variable_get(self::EXCLUDED_SERVICES_KEY, array()); |
|
267 |
} |
|
268 |
|
|
393 | 269 |
/** |
394 |
* Return the type of loading.
|
|
270 |
* Return the type of inclusion.
|
|
395 | 271 |
* |
396 | 272 |
* @return string |
397 | 273 |
* Retuns domready or async. |
398 | 274 |
*/ |
399 |
public function getWidgetJsLoadType() { |
|
400 |
return variable_get(self::WIDGET_JS_LOAD_TYPE, self::DEFAULT_WIDGET_JS_LOAD_TYPE); |
|
275 |
public function getWidgetJsInclude() { |
|
276 |
return variable_get(self::WIDGET_JS_INCLUDE, self::DEFAULT_WIDGET_JS_INCLUDE); |
|
277 |
} |
|
278 |
|
|
279 |
/** |
|
280 |
* Return if domready loading should be active. |
|
281 |
* |
|
282 |
* @return bool |
|
283 |
* Returns TRUE if domready is enabled. |
|
284 |
*/ |
|
285 |
public function getWidgetJsDomReady() { |
|
286 |
return variable_get(self::WIDGET_JS_LOAD_DOMREADY, self::DEFAULT_WIDGET_JS_LOAD_DOMREADY); |
|
287 |
} |
|
288 |
|
|
289 |
/** |
|
290 |
* Return if async initialization should be active. |
|
291 |
* |
|
292 |
* @return bool |
|
293 |
* Returns TRUE if async is enabled. |
|
294 |
*/ |
|
295 |
public function getWidgetJsAsync() { |
|
296 |
return variable_get(self::WIDGET_JS_LOAD_ASYNC, self::DEFAULT_WIDGET_JS_LOAD_ASYNC); |
|
401 | 297 |
} |
402 | 298 |
|
403 | 299 |
public function isClickToOpenCompactMenuEnabled() { |
... | ... | |
485 | 381 |
return $this->getBaseBookmarkUrl() . $this->getProfileIdQueryParameterPrefixedWithAmp(); |
486 | 382 |
} |
487 | 383 |
|
384 |
/** |
|
385 |
* Transform the entity title to a attribute. |
|
386 |
* |
|
387 |
* @remarks |
|
388 |
* The title of the entity and site can not contain double-qoutes. These are |
|
389 |
* encoded into html chars. |
|
390 |
*/ |
|
488 | 391 |
private function getAttributeTitle($entity) { |
489 | 392 |
if (isset($entity->title)) { |
490 | 393 |
return array( |
491 |
self::TITLE_ATTRIBUTE => (check_plain($entity->title) . ' - ' . variable_get('site_name')),
|
|
394 |
self::TITLE_ATTRIBUTE => htmlentities($entity->title . ' - ' . variable_get('site_name'), ENT_COMPAT),
|
|
492 | 395 |
); |
493 | 396 |
} |
494 | 397 |
return array(); |
... | ... | |
503 | 406 |
return array(); |
504 | 407 |
} |
505 | 408 |
|
506 |
private function getServiceNamesAsCommaSeparatedString() {
|
|
507 |
$enabledServiceNames = array_values($this->getEnabledServices());
|
|
508 |
$enabledServicesAsCommaSeparatedString = '';
|
|
509 |
foreach ($enabledServiceNames as $enabledServiceName) {
|
|
510 |
if ($enabledServiceName != '0') {
|
|
511 |
$enabledServicesAsCommaSeparatedString .= $enabledServiceName . ',';
|
|
409 |
public function getServiceNamesAsCommaSeparatedString($services) {
|
|
410 |
$serviceNames = array_values($services);
|
|
411 |
$servicesAsCommaSeparatedString = '';
|
|
412 |
foreach ($serviceNames as $serviceName) {
|
|
413 |
if ($serviceName != '0') {
|
|
414 |
$servicesAsCommaSeparatedString .= $serviceName . ',';
|
|
512 | 415 |
} |
513 | 416 |
} |
514 |
return $enabledServicesAsCommaSeparatedString;
|
|
417 |
return $servicesAsCommaSeparatedString;
|
|
515 | 418 |
} |
516 | 419 |
|
517 | 420 |
private function getAdminCssFilePath() { |
drupal7/sites/all/modules/addthis/classes/Services/AddThisScriptManager.php | ||
---|---|---|
1 |
<?php |
|
2 |
/** |
|
3 |
* @file |
|
4 |
* Class definition of a script manager. |
|
5 |
* |
|
6 |
* This class will be used on different places. The result of the attachJsToElement() |
|
7 |
* should be the same in every situation within one request and throughout the |
|
8 |
* loading of the site. |
|
9 |
* |
|
10 |
* When manipulating the configuration do this very early in the request. This |
|
11 |
* could be hook_init() for example. Any other method should be before hook_page_build(). |
|
12 |
* The implementation of addthis_page_build() is the first known instance where |
|
13 |
* this class might get used based on the configuration. |
|
14 |
*/ |
|
15 |
|
|
16 |
class AddThisScriptManager { |
|
17 |
|
|
18 |
private $addthis = NULL; |
|
19 |
private $async = NULL; |
|
20 |
private $domready = NULL; |
|
21 |
|
|
22 |
/** |
|
23 |
* Construct method. |
|
24 |
*/ |
|
25 |
private function __construct() { |
|
26 |
$this->addthis = AddThis::getInstance(); |
|
27 |
|
|
28 |
$this->async = $this->addthis->getWidgetJsAsync(); |
|
29 |
$this->domready = $this->addthis->getWidgetJsDomReady(); |
|
30 |
} |
|
31 |
|
|
32 |
/** |
|
33 |
* Return a single instance of the AddThisScriptManager. |
|
34 |
* |
|
35 |
* @return AddThisScriptManager |
|
36 |
*/ |
|
37 |
public static function getInstance() { |
|
38 |
static $manager; |
|
39 |
|
|
40 |
if (!isset($manager)) { |
|
41 |
$manager = new AddThisScriptManager(); |
|
42 |
} |
|
43 |
return $manager; |
|
44 |
} |
|
45 |
|
|
46 |
/** |
|
47 |
* Get the current widget js url. |
|
48 |
* |
|
49 |
* @return string |
|
50 |
* A url reference to the widget js. |
|
51 |
*/ |
|
52 |
public function getWidgetJsUrl() { |
|
53 |
return check_url(variable_get(AddThis::WIDGET_JS_URL_KEY, AddThis::DEFAULT_WIDGET_JS_URL)); |
|
54 |
} |
|
55 |
|
|
56 |
/** |
|
57 |
* Return if we are on https connection. |
|
58 |
* |
|
59 |
* @return bool |
|
60 |
* TRUE if the current request is on https. |
|
61 |
*/ |
|
62 |
public function isHttps() { |
|
63 |
global $is_https; |
|
64 |
|
|
65 |
return $is_https; |
|
66 |
} |
|
67 |
|
|
68 |
/** |
|
69 |
* Change the schema from http to https if we are on https. |
|
70 |
* |
|
71 |
* @param string $url |
|
72 |
* A full url. |
|
73 |
* |
|
74 |
* @return string |
|
75 |
* The changed url. |
|
76 |
*/ |
|
77 |
public function correctSchemaIfHttps($url) { |
|
78 |
if (is_string($url) && $this->isHttps()) { |
|
79 |
return str_replace('http://', 'https://', $url); |
|
80 |
} |
|
81 |
else { |
|
82 |
return $url; |
|
83 |
} |
|
84 |
throw new InvalidArgumentException('The argument was not a string value'); |
|
85 |
} |
|
86 |
|
|
87 |
/** |
|
88 |
* Attach the widget js to the element. |
|
89 |
* |
|
90 |
* @todo Change the scope of the addthis.js. |
|
91 |
* See if we can get the scope of the addthis.js into the header |
|
92 |
* just below the settings so that the settings can be used in the loaded |
|
93 |
* addthis.js of our module. |
|
94 |
* |
|
95 |
* @param array $element |
|
96 |
* The element to attach the JavaScript to. |
|
97 |
*/ |
|
98 |
public function attachJsToElement(&$element) { |
|
99 |
|
|
100 |
if ($this->addthis->getWidgetJsInclude() != AddThis::WIDGET_JS_INCLUDE_NONE) { |
|
101 |
$widget_js = new AddThisWidgetJsUrl($this->getWidgetJsUrl()); |
|
102 |
|
|
103 |
$pubid = $this->addthis->getProfileId(); |
|
104 |
if (isset($pubid) && !empty($pubid) && is_string($pubid)) { |
|
105 |
$widget_js->addAttribute('pubid', $pubid); |
|
106 |
} |
|
107 |
|
|
108 |
$async = $this->async; |
|
109 |
if ($async) { |
|
110 |
$widget_js->addAttribute('async', 1); |
|
111 |
} |
|
112 |
|
|
113 |
$domready = $this->domready; |
|
114 |
if ($domready) { |
|
115 |
$widget_js->addAttribute('domready', 1); |
|
116 |
} |
|
117 |
|
|
118 |
// Only when the script is not loaded after the DOM is ready we include |
|
119 |
// the script with #attached. |
|
120 |
if (!$domready) { |
|
121 |
$element['#attached']['js'][$this->getWidgetJsUrl()] = array( |
|
122 |
'type' => 'external', |
|
123 |
'scope' => 'footer', |
|
124 |
); |
|
125 |
} |
|
126 |
|
|
127 |
// Every setting value passed here overrides previously set values but |
|
128 |
// leaves the values that are already set somewhere else and that are not |
Formats disponibles : Unified diff
Weekly update of contrib modules