Projet

Général

Profil

Révision 16a50439

Ajouté par Florent Torregrosa il y a presque 6 ans

Issue #886: migration to Matomo module.

Voir les différences:

bin/d7-reset-matomo-variables.sh
1
#!/bin/sh
2

  
3
site="$1"
4

  
5
###### Common to all sites
6
drush @"${site}" -yq en matomo
7
drush @"${site}" -yq vset matomo_url_http "http://piwik.centrale-marseille.fr/"
8
drush @"${site}" -yq vset matomo_url_https "https://piwik.centrale-marseille.fr/"
9
# Matomo cache.
10
drush @"${site}" -yq vset matomo_cache 1
11
drush @"${site}" -yq vset matomo_visibility_roles "1"
12
# Matomo is enable for everyone except the administrator
13
drush @"${site}" -yq vset --format=json matomo_roles '[3]'
14
drush @"${site}" -yq vset matomo_page_title_hierarchy 1
15
# Activate local search.
16
drush @"${site}" -yq vset matomo_site_search 1
17

  
18
##### Specific
19
# Note: you can read the matomo site id from the url in matomo
20
case "$1" in
21
    accueil)
22
	matomo_id=286
23
	;;
24
    agora)
25
	matomo_id=116
26
	;;
27
    bda)
28
	matomo_id=273
29
	;;
30
    bde)
31
	matomo_id=274
32
	;;
33
    bds)
34
	matomo_id=275
35
	;;
36
    cac13)
37
	matomo_id=276
38
	;;
39
    cheer-up)
40
	matomo_id=277
41
	;;
42
    clubfinance)
43
	matomo_id=278
44
	;;
45
    clubrobot)
46
	matomo_id=279
47
	;;
48
    echangesphoceens)
49
	matomo_id=280
50
	;;
51
    eluseleves)
52
	matomo_id=281
53
	;;
54
    ercm)
55
	matomo_id=282
56
	;;
57
    fablab)
58
	matomo_id=151
59
	;;
60
    forumentreprises)
61
	matomo_id=270
62
	;;
63
    ginfo)
64
	matomo_id=283
65
	;;
66
    icm)
67
	matomo_id=284
68
	;;
69
    isf)
70
	matomo_id=285
71
	;;
72
    ksi)
73
	matomo_id=209
74
	;;
75
    mdv)
76
	matomo_id=99
77
	;;
78
    tvp)
79
	matomo_id=110
80
	;;
81
    ftorregrosa)
82
	matomo_id=314
83
	;;
84
    default)
85
	matomo_id=101
86
	;;
87
    *)
88
	matomo_id=287
89
	;;
90
esac
91

  
92
drush @"${site}" -yq vset matomo_site_id "${matomo_id}"
bin/d7-reset-piwik-variables.sh
1
#!/bin/sh
2

  
3
site="$1"
4

  
5
###### Common to all sites
6
drush @"${site}" -yq en piwik
7
drush @"${site}" -yq vset piwik_url_http "http://piwik.centrale-marseille.fr/"
8
drush @"${site}" -yq vset piwik_url_https "https://piwik.centrale-marseille.fr/"
9
# Piwik cache.
10
drush @"${site}" -yq vset piwik_cache 1
11
drush @"${site}" -yq vset piwik_visibility_roles "1"
12
# Piwik is enable for everyone except the administrator
13
drush @"${site}" -yq vset --format=json piwik_roles '[3]'
14
drush @"${site}" -yq vset piwik_page_title_hierarchy 1
15
# Activate local search.
16
drush @"${site}" -yq vset piwik_site_search 1
17

  
18
##### Specific
19
# Note: you can read the piwik site id from the url in piwik
20
case "$1" in
21
    accueil)
22
	piwik_id=286
23
	;;
24
    agora)
25
	piwik_id=116
26
	;;
27
    bda)
28
	piwik_id=273
29
	;;
30
    bde)
31
	piwik_id=274
32
	;;
33
    bds)
34
	piwik_id=275
35
	;;
36
    cac13)
37
	piwik_id=276
38
	;;
39
    cheer-up)
40
	piwik_id=277
41
	;;
42
    clubfinance)
43
	piwik_id=278
44
	;;
45
    clubrobot)
46
	piwik_id=279
47
	;;
48
    echangesphoceens)
49
	piwik_id=280
50
	;;
51
    eluseleves)
52
	piwik_id=281
53
	;;
54
    ercm)
55
	piwik_id=282
56
	;;
57
    fablab)
58
	piwik_id=151
59
	;;
60
    forumentreprises)
61
	piwik_id=270
62
	;;
63
    ginfo)
64
	piwik_id=283
65
	;;
66
    icm)
67
	piwik_id=284
68
	;;
69
    isf)
70
	piwik_id=285
71
	;;
72
    ksi)
73
	piwik_id=209
74
	;;
75
    mdv)
76
	piwik_id=99
77
	;;
78
    tvp)
79
	piwik_id=110
80
	;;
81
    ftorregrosa)
82
	piwik_id=314
83
	;;
84
    default)
85
	piwik_id=101
86
	;;
87
    *)
88
	piwik_id=287
89
	;;
90
esac
91

  
92
drush @"${site}" -yq vset piwik_site_id "${piwik_id}"
bin/d7-reset-variables.sh
36 36
drush @"${site}" -yq vset hidden_captcha_label "$random_1 + $random_2"
37 37

  
38 38

  
39
####### Piwik
40
d7-reset-piwik-variables.sh "${site}"
39
####### Matomo
40
d7-reset-matomo-variables.sh "${site}"
41 41

  
42 42
###### Security review
43 43
# For untrusted roles:
drupal7/sites/all/modules/piwik/LICENSE.txt
1
                    GNU GENERAL PUBLIC LICENSE
2
                       Version 2, June 1991
3

  
4
 Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6
 Everyone is permitted to copy and distribute verbatim copies
7
 of this license document, but changing it is not allowed.
8

  
9
                            Preamble
10

  
11
  The licenses for most software are designed to take away your
12
freedom to share and change it.  By contrast, the GNU General Public
13
License is intended to guarantee your freedom to share and change free
14
software--to make sure the software is free for all its users.  This
15
General Public License applies to most of the Free Software
16
Foundation's software and to any other program whose authors commit to
17
using it.  (Some other Free Software Foundation software is covered by
18
the GNU Lesser General Public License instead.)  You can apply it to
19
your programs, too.
20

  
21
  When we speak of free software, we are referring to freedom, not
22
price.  Our General Public Licenses are designed to make sure that you
23
have the freedom to distribute copies of free software (and charge for
24
this service if you wish), that you receive source code or can get it
25
if you want it, that you can change the software or use pieces of it
26
in new free programs; and that you know you can do these things.
27

  
28
  To protect your rights, we need to make restrictions that forbid
29
anyone to deny you these rights or to ask you to surrender the rights.
30
These restrictions translate to certain responsibilities for you if you
31
distribute copies of the software, or if you modify it.
32

  
33
  For example, if you distribute copies of such a program, whether
34
gratis or for a fee, you must give the recipients all the rights that
35
you have.  You must make sure that they, too, receive or can get the
36
source code.  And you must show them these terms so they know their
37
rights.
38

  
39
  We protect your rights with two steps: (1) copyright the software, and
40
(2) offer you this license which gives you legal permission to copy,
41
distribute and/or modify the software.
42

  
43
  Also, for each author's protection and ours, we want to make certain
44
that everyone understands that there is no warranty for this free
45
software.  If the software is modified by someone else and passed on, we
46
want its recipients to know that what they have is not the original, so
47
that any problems introduced by others will not reflect on the original
48
authors' reputations.
49

  
50
  Finally, any free program is threatened constantly by software
51
patents.  We wish to avoid the danger that redistributors of a free
52
program will individually obtain patent licenses, in effect making the
53
program proprietary.  To prevent this, we have made it clear that any
54
patent must be licensed for everyone's free use or not licensed at all.
55

  
56
  The precise terms and conditions for copying, distribution and
57
modification follow.
58

  
59
                    GNU GENERAL PUBLIC LICENSE
60
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61

  
62
  0. This License applies to any program or other work which contains
63
a notice placed by the copyright holder saying it may be distributed
64
under the terms of this General Public License.  The "Program", below,
65
refers to any such program or work, and a "work based on the Program"
66
means either the Program or any derivative work under copyright law:
67
that is to say, a work containing the Program or a portion of it,
68
either verbatim or with modifications and/or translated into another
69
language.  (Hereinafter, translation is included without limitation in
70
the term "modification".)  Each licensee is addressed as "you".
71

  
72
Activities other than copying, distribution and modification are not
73
covered by this License; they are outside its scope.  The act of
74
running the Program is not restricted, and the output from the Program
75
is covered only if its contents constitute a work based on the
76
Program (independent of having been made by running the Program).
77
Whether that is true depends on what the Program does.
78

  
79
  1. You may copy and distribute verbatim copies of the Program's
80
source code as you receive it, in any medium, provided that you
81
conspicuously and appropriately publish on each copy an appropriate
82
copyright notice and disclaimer of warranty; keep intact all the
83
notices that refer to this License and to the absence of any warranty;
84
and give any other recipients of the Program a copy of this License
85
along with the Program.
86

  
87
You may charge a fee for the physical act of transferring a copy, and
88
you may at your option offer warranty protection in exchange for a fee.
89

  
90
  2. You may modify your copy or copies of the Program or any portion
91
of it, thus forming a work based on the Program, and copy and
92
distribute such modifications or work under the terms of Section 1
93
above, provided that you also meet all of these conditions:
94

  
95
    a) You must cause the modified files to carry prominent notices
96
    stating that you changed the files and the date of any change.
97

  
98
    b) You must cause any work that you distribute or publish, that in
99
    whole or in part contains or is derived from the Program or any
100
    part thereof, to be licensed as a whole at no charge to all third
101
    parties under the terms of this License.
102

  
103
    c) If the modified program normally reads commands interactively
104
    when run, you must cause it, when started running for such
105
    interactive use in the most ordinary way, to print or display an
106
    announcement including an appropriate copyright notice and a
107
    notice that there is no warranty (or else, saying that you provide
108
    a warranty) and that users may redistribute the program under
109
    these conditions, and telling the user how to view a copy of this
110
    License.  (Exception: if the Program itself is interactive but
111
    does not normally print such an announcement, your work based on
112
    the Program is not required to print an announcement.)
113

  
114
These requirements apply to the modified work as a whole.  If
115
identifiable sections of that work are not derived from the Program,
116
and can be reasonably considered independent and separate works in
117
themselves, then this License, and its terms, do not apply to those
118
sections when you distribute them as separate works.  But when you
119
distribute the same sections as part of a whole which is a work based
120
on the Program, the distribution of the whole must be on the terms of
121
this License, whose permissions for other licensees extend to the
122
entire whole, and thus to each and every part regardless of who wrote it.
123

  
124
Thus, it is not the intent of this section to claim rights or contest
125
your rights to work written entirely by you; rather, the intent is to
126
exercise the right to control the distribution of derivative or
127
collective works based on the Program.
128

  
129
In addition, mere aggregation of another work not based on the Program
130
with the Program (or with a work based on the Program) on a volume of
131
a storage or distribution medium does not bring the other work under
132
the scope of this License.
133

  
134
  3. You may copy and distribute the Program (or a work based on it,
135
under Section 2) in object code or executable form under the terms of
136
Sections 1 and 2 above provided that you also do one of the following:
137

  
138
    a) Accompany it with the complete corresponding machine-readable
139
    source code, which must be distributed under the terms of Sections
140
    1 and 2 above on a medium customarily used for software interchange; or,
141

  
142
    b) Accompany it with a written offer, valid for at least three
143
    years, to give any third party, for a charge no more than your
144
    cost of physically performing source distribution, a complete
145
    machine-readable copy of the corresponding source code, to be
146
    distributed under the terms of Sections 1 and 2 above on a medium
147
    customarily used for software interchange; or,
148

  
149
    c) Accompany it with the information you received as to the offer
150
    to distribute corresponding source code.  (This alternative is
151
    allowed only for noncommercial distribution and only if you
152
    received the program in object code or executable form with such
153
    an offer, in accord with Subsection b above.)
154

  
155
The source code for a work means the preferred form of the work for
156
making modifications to it.  For an executable work, complete source
157
code means all the source code for all modules it contains, plus any
158
associated interface definition files, plus the scripts used to
159
control compilation and installation of the executable.  However, as a
160
special exception, the source code distributed need not include
161
anything that is normally distributed (in either source or binary
162
form) with the major components (compiler, kernel, and so on) of the
163
operating system on which the executable runs, unless that component
164
itself accompanies the executable.
165

  
166
If distribution of executable or object code is made by offering
167
access to copy from a designated place, then offering equivalent
168
access to copy the source code from the same place counts as
169
distribution of the source code, even though third parties are not
170
compelled to copy the source along with the object code.
171

  
172
  4. You may not copy, modify, sublicense, or distribute the Program
173
except as expressly provided under this License.  Any attempt
174
otherwise to copy, modify, sublicense or distribute the Program is
175
void, and will automatically terminate your rights under this License.
176
However, parties who have received copies, or rights, from you under
177
this License will not have their licenses terminated so long as such
178
parties remain in full compliance.
179

  
180
  5. You are not required to accept this License, since you have not
181
signed it.  However, nothing else grants you permission to modify or
182
distribute the Program or its derivative works.  These actions are
183
prohibited by law if you do not accept this License.  Therefore, by
184
modifying or distributing the Program (or any work based on the
185
Program), you indicate your acceptance of this License to do so, and
186
all its terms and conditions for copying, distributing or modifying
187
the Program or works based on it.
188

  
189
  6. Each time you redistribute the Program (or any work based on the
190
Program), the recipient automatically receives a license from the
191
original licensor to copy, distribute or modify the Program subject to
192
these terms and conditions.  You may not impose any further
193
restrictions on the recipients' exercise of the rights granted herein.
194
You are not responsible for enforcing compliance by third parties to
195
this License.
196

  
197
  7. If, as a consequence of a court judgment or allegation of patent
198
infringement or for any other reason (not limited to patent issues),
199
conditions are imposed on you (whether by court order, agreement or
200
otherwise) that contradict the conditions of this License, they do not
201
excuse you from the conditions of this License.  If you cannot
202
distribute so as to satisfy simultaneously your obligations under this
203
License and any other pertinent obligations, then as a consequence you
204
may not distribute the Program at all.  For example, if a patent
205
license would not permit royalty-free redistribution of the Program by
206
all those who receive copies directly or indirectly through you, then
207
the only way you could satisfy both it and this License would be to
208
refrain entirely from distribution of the Program.
209

  
210
If any portion of this section is held invalid or unenforceable under
211
any particular circumstance, the balance of the section is intended to
212
apply and the section as a whole is intended to apply in other
213
circumstances.
214

  
215
It is not the purpose of this section to induce you to infringe any
216
patents or other property right claims or to contest validity of any
217
such claims; this section has the sole purpose of protecting the
218
integrity of the free software distribution system, which is
219
implemented by public license practices.  Many people have made
220
generous contributions to the wide range of software distributed
221
through that system in reliance on consistent application of that
222
system; it is up to the author/donor to decide if he or she is willing
223
to distribute software through any other system and a licensee cannot
224
impose that choice.
225

  
226
This section is intended to make thoroughly clear what is believed to
227
be a consequence of the rest of this License.
228

  
229
  8. If the distribution and/or use of the Program is restricted in
230
certain countries either by patents or by copyrighted interfaces, the
231
original copyright holder who places the Program under this License
232
may add an explicit geographical distribution limitation excluding
233
those countries, so that distribution is permitted only in or among
234
countries not thus excluded.  In such case, this License incorporates
235
the limitation as if written in the body of this License.
236

  
237
  9. The Free Software Foundation may publish revised and/or new versions
238
of the General Public License from time to time.  Such new versions will
239
be similar in spirit to the present version, but may differ in detail to
240
address new problems or concerns.
241

  
242
Each version is given a distinguishing version number.  If the Program
243
specifies a version number of this License which applies to it and "any
244
later version", you have the option of following the terms and conditions
245
either of that version or of any later version published by the Free
246
Software Foundation.  If the Program does not specify a version number of
247
this License, you may choose any version ever published by the Free Software
248
Foundation.
249

  
250
  10. If you wish to incorporate parts of the Program into other free
251
programs whose distribution conditions are different, write to the author
252
to ask for permission.  For software which is copyrighted by the Free
253
Software Foundation, write to the Free Software Foundation; we sometimes
254
make exceptions for this.  Our decision will be guided by the two goals
255
of preserving the free status of all derivatives of our free software and
256
of promoting the sharing and reuse of software generally.
257

  
258
                            NO WARRANTY
259

  
260
  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
262
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
266
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
267
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268
REPAIR OR CORRECTION.
269

  
270
  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278
POSSIBILITY OF SUCH DAMAGES.
279

  
280
                     END OF TERMS AND CONDITIONS
281

  
282
            How to Apply These Terms to Your New Programs
283

  
284
  If you develop a new program, and you want it to be of the greatest
285
possible use to the public, the best way to achieve this is to make it
286
free software which everyone can redistribute and change under these terms.
287

  
288
  To do so, attach the following notices to the program.  It is safest
289
to attach them to the start of each source file to most effectively
290
convey the exclusion of warranty; and each file should have at least
291
the "copyright" line and a pointer to where the full notice is found.
292

  
293
    <one line to give the program's name and a brief idea of what it does.>
294
    Copyright (C) <year>  <name of author>
295

  
296
    This program is free software; you can redistribute it and/or modify
297
    it under the terms of the GNU General Public License as published by
298
    the Free Software Foundation; either version 2 of the License, or
299
    (at your option) any later version.
300

  
301
    This program is distributed in the hope that it will be useful,
302
    but WITHOUT ANY WARRANTY; without even the implied warranty of
303
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
304
    GNU General Public License for more details.
305

  
306
    You should have received a copy of the GNU General Public License along
307
    with this program; if not, write to the Free Software Foundation, Inc.,
308
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309

  
310
Also add information on how to contact you by electronic and paper mail.
311

  
312
If the program is interactive, make it output a short notice like this
313
when it starts in an interactive mode:
314

  
315
    Gnomovision version 69, Copyright (C) year name of author
316
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317
    This is free software, and you are welcome to redistribute it
318
    under certain conditions; type `show c' for details.
319

  
320
The hypothetical commands `show w' and `show c' should show the appropriate
321
parts of the General Public License.  Of course, the commands you use may
322
be called something other than `show w' and `show c'; they could even be
323
mouse-clicks or menu items--whatever suits your program.
324

  
325
You should also get your employer (if you work as a programmer) or your
326
school, if any, to sign a "copyright disclaimer" for the program, if
327
necessary.  Here is a sample; alter the names:
328

  
329
  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330
  `Gnomovision' (which makes passes at compilers) written by James Hacker.
331

  
332
  <signature of Ty Coon>, 1 April 1989
333
  Ty Coon, President of Vice
334

  
335
This General Public License does not permit incorporating your program into
336
proprietary programs.  If your program is a subroutine library, you may
337
consider it more useful to permit linking proprietary applications with the
338
library.  If this is what you want to do, use the GNU Lesser General
339
Public License instead of this License.
drupal7/sites/all/modules/piwik/README.txt
1

  
2
Module: Piwik - Web analytics
3
Author: Alexander Hass <http://www.hass.de/>
4

  
5

  
6
Description
7
===========
8
Adds the Piwik tracking system to your website.
9

  
10
Requirements
11
============
12

  
13
* Piwik installation
14
* Piwik website account
15

  
16

  
17
Installation
18
============
19
* Copy the 'piwik' module directory in to your Drupal
20
sites/all/modules directory as usual.
21

  
22

  
23
Usage
24
=====
25
In the settings page enter your Piwik website ID.
26

  
27
You will also need to define what user roles should be tracked.
28
Simply tick the roles you would like to monitor.
29

  
30
All pages will now have the required JavaScript added to the
31
HTML footer can confirm this by viewing the page source from
32
your browser.
33

  
34

  
35
Custom variables
36
=================
37
One example for custom variables tracking is the "User roles" tracking. Enter
38
the below configuration data into the custom variables settings form under
39
admin/config/system/piwik.
40

  
41
Slot: 1
42
Name: User roles
43
Value: [current-user:piwik-role-names]
44
Scope: Visitor
45

  
46
Slot: 1
47
Name: User ids
48
Value: [current-user:piwik-role-ids]
49
Scope: Visitor
50

  
51
More details about custom variables can be found in the Piwik API documentation
52
at http://piwik.org/docs/javascript-tracking/#toc-custom-variables.
53

  
54

  
55
Advanced Settings
56
=================
57
You can include additional JavaScript snippets in the advanced
58
textarea. These can be found on various blog posts, or on the
59
official Piwik pages. Support is not provided for any customisations
60
you include.
61

  
62
To speed up page loading you may also cache the piwik.js
63
file locally. You need to make sure the site file system is in public
64
download mode.
65

  
66

  
67
Known issues
68
============
69
Drupal requirements (http://drupal.org/requirements) tell you to configure 
70
PHP with "session.save_handler = user", but your Piwik installation may
71
not work with this configuration and gives you a server error 500.
72

  
73
1. You are able to workaround with the PHP default in your php.ini:
74

  
75
   [Session]
76
   session.save_handler = files
77

  
78
2. With Apache you may overwrite the PHP setting for the Piwik directory only.
79
   If Piwik is installed in /piwik you are able to create a .htaccess file in
80
   this directory with the below code:
81

  
82
   # PHP 4, Apache 1.
83
   <IfModule mod_php4.c>
84
     php_value session.save_handler files
85
   </IfModule>
86

  
87
   # PHP 4, Apache 2.
88
   <IfModule sapi_apache2.c>
89
     php_value session.save_handler files
90
   </IfModule>
91

  
92
   # PHP 5, Apache 1 and 2.
93
   <IfModule mod_php5.c>
94
     php_value session.save_handler files
95
   </IfModule>
drupal7/sites/all/modules/piwik/piwik.admin.inc
1
<?php
2

  
3
/**
4
 * @file
5
 * Administrative page callbacks for the piwik module.
6
 */
7

  
8
/**
9
 * Implements hook_admin_settings() for configuring the module.
10
 */
11
function piwik_admin_settings_form($form_state) {
12
  $form['account'] = array(
13
    '#type' => 'fieldset',
14
    '#title' => t('General settings'),
15
  );
16

  
17
  $form['account']['piwik_site_id'] = array(
18
    '#type' => 'textfield',
19
    '#title' => t('Piwik site ID'),
20
    '#default_value' => variable_get('piwik_site_id', ''),
21
    '#size' => 15,
22
    '#maxlength' => 20,
23
    '#required' => TRUE,
24
    '#description' => t('The user account number is unique to the websites domain. Click the <strong>Settings</strong> link in your Piwik account, then the <strong>Websites</strong> tab and enter the appropriate site <strong>ID</strong> into this field.'),
25
  );
26
  $form['account']['piwik_url_http'] = array(
27
    '#type' => 'textfield',
28
    '#title' => t('Piwik HTTP URL'),
29
    '#default_value' => variable_get('piwik_url_http', ''),
30
    '#size' => 80,
31
    '#maxlength' => 255,
32
    '#required' => TRUE,
33
    '#description' => t('The URL to your Piwik base directory. Example: "http://www.example.com/piwik/".'),
34
  );
35
  $form['account']['piwik_url_https'] = array(
36
    '#type' => 'textfield',
37
    '#title' => t('Piwik HTTPS URL'),
38
    '#default_value' => variable_get('piwik_url_https', ''),
39
    '#size' => 80,
40
    '#maxlength' => 255,
41
    '#description' => t('The URL to your Piwik base directory with SSL certificate installed. Required if you track a SSL enabled website. Example: "https://www.example.com/piwik/".'),
42
  );
43
  // Required for automated form save testing only.
44
  $form['account']['piwik_url_skiperror'] = array(
45
    '#type' => 'hidden',
46
    '#default_value' => FALSE,
47
  );
48

  
49
  // Visibility settings.
50
  $form['tracking_title'] = array(
51
    '#type' => 'item',
52
    '#title' => t('Tracking scope'),
53
  );
54
  $form['tracking'] = array(
55
    '#type' => 'vertical_tabs',
56
    '#attached' => array(
57
      'js' => array(drupal_get_path('module', 'piwik') . '/piwik.admin.js'),
58
    ),
59
  );
60

  
61
  $form['tracking']['domain_tracking'] = array(
62
    '#type' => 'fieldset',
63
    '#title' => t('Domains'),
64
  );
65

  
66
  global $cookie_domain;
67
  $multiple_sub_domains = array();
68
  foreach (array('www', 'app', 'shop') as $subdomain) {
69
    if (count(explode('.', $cookie_domain)) > 2 && !is_numeric(str_replace('.', '', $cookie_domain))) {
70
      $multiple_sub_domains[] = $subdomain . $cookie_domain;
71
    }
72
    // IP addresses or localhost.
73
    else {
74
      $multiple_sub_domains[] = $subdomain . '.example.com';
75
    }
76
  }
77

  
78
  $form['tracking']['domain_tracking']['piwik_domain_mode'] = array(
79
    '#type' => 'radios',
80
    '#title' => t('What are you tracking?'),
81
    '#options' => array(
82
      0 => t('A single domain (default)') . '<div class="description">' . t('Domain: @domain', array('@domain' => $_SERVER['HTTP_HOST'])) . '</div>',
83
      1 => t('One domain with multiple subdomains') . '<div class="description">' . t('Examples: @domains', array('@domains' => implode(', ', $multiple_sub_domains))) . '</div>',
84
    ),
85
    '#default_value' => variable_get('piwik_domain_mode', 0),
86
  );
87

  
88
  // Page specific visibility configurations.
89
  $php_access = user_access('use PHP for tracking visibility');
90
  $visibility = variable_get('piwik_visibility_pages', 0);
91
  $pages = variable_get('piwik_pages', PIWIK_PAGES);
92

  
93
  $form['tracking']['page_vis_settings'] = array(
94
    '#type' => 'fieldset',
95
    '#title' => t('Pages'),
96
    '#collapsible' => TRUE,
97
    '#collapsed' => TRUE,
98
  );
99

  
100
  if ($visibility == 2 && !$php_access) {
101
    $form['tracking']['page_vis_settings'] = array();
102
    $form['tracking']['page_vis_settings']['piwik_visibility_pages'] = array('#type' => 'value', '#value' => 2);
103
    $form['tracking']['page_vis_settings']['piwik_pages'] = array('#type' => 'value', '#value' => $pages);
104
  }
105
  else {
106
    $options = array(
107
      t('Every page except the listed pages'),
108
      t('The listed pages only')
109
    );
110
    $description = t("Specify pages by using their paths. Enter one path per line. The '*' character is a wildcard. Example paths are %blog for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => 'blog', '%blog-wildcard' => 'blog/*', '%front' => '<front>'));
111

  
112
    if (module_exists('php') && $php_access) {
113
      $options[] = t('Pages on which this PHP code returns <code>TRUE</code> (experts only)');
114
      $title = t('Pages or PHP code');
115
      $description .= ' ' . t('If the PHP option is chosen, enter PHP code between %php. Note that executing incorrect PHP code can break your Drupal site.', array('%php' => '<?php ?>'));
116
    }
117
    else {
118
      $title = t('Pages');
119
    }
120
    $form['tracking']['page_vis_settings']['piwik_visibility_pages'] = array(
121
      '#type' => 'radios',
122
      '#title' => t('Add tracking to specific pages'),
123
      '#options' => $options,
124
      '#default_value' => $visibility,
125
    );
126
    $form['tracking']['page_vis_settings']['piwik_pages'] = array(
127
      '#type' => 'textarea',
128
      '#title' => $title,
129
      '#title_display' => 'invisible',
130
      '#default_value' => $pages,
131
      '#description' => $description,
132
      '#rows' => 10,
133
    );
134
  }
135

  
136
  // Render the role overview.
137
  $form['tracking']['role_vis_settings'] = array(
138
    '#type' => 'fieldset',
139
    '#title' => t('Roles'),
140
  );
141

  
142
  $form['tracking']['role_vis_settings']['piwik_visibility_roles'] = array(
143
    '#type' => 'radios',
144
    '#title' => t('Add tracking for specific roles'),
145
    '#options' => array(
146
      t('Add to the selected roles only'),
147
      t('Add to every role except the selected ones'),
148
    ),
149
    '#default_value' => variable_get('piwik_visibility_roles', 0),
150
  );
151

  
152
  $role_options = array_map('check_plain', user_roles());
153
  $form['tracking']['role_vis_settings']['piwik_roles'] = array(
154
    '#type' => 'checkboxes',
155
    '#title' => t('Roles'),
156
    '#default_value' => variable_get('piwik_roles', array()),
157
    '#options' => $role_options,
158
    '#description' => t('If none of the roles are selected, all users will be tracked. If a user has any of the roles checked, that user will be tracked (or excluded, depending on the setting above).'),
159
  );
160

  
161
  // Standard tracking configurations.
162
  $form['tracking']['user_vis_settings'] = array(
163
    '#type' => 'fieldset',
164
    '#title' => t('Users'),
165
  );
166
  $t_permission = array('%permission' => t('opt-in or out of tracking'));
167
  $form['tracking']['user_vis_settings']['piwik_custom'] = array(
168
    '#type' => 'radios',
169
    '#title' => t('Allow users to customize tracking on their account page'),
170
    '#options' => array(
171
      t('No customization allowed'),
172
      t('Tracking on by default, users with %permission permission can opt out', $t_permission),
173
      t('Tracking off by default, users with %permission permission can opt in', $t_permission)
174
    ),
175
    '#default_value' => variable_get('piwik_custom', 0),
176
  );
177
  $form['tracking']['user_vis_settings']['piwik_trackuserid'] = array(
178
    '#type' => 'checkbox',
179
    '#title' => t('Track User ID'),
180
    '#default_value' => variable_get('piwik_trackuserid', 0),
181
    '#description' => t('User ID enables the analysis of groups of sessions, across devices, using a unique, persistent, and non-personally identifiable ID string representing a user. <a href="@url">Learn more about the benefits of using User ID</a>.', array('@url' => 'http://piwik.org/docs/user-id/')),
182
  );
183

  
184
  // Link specific configurations.
185
  $form['tracking']['linktracking'] = array(
186
    '#type' => 'fieldset',
187
    '#title' => t('Links and downloads'),
188
  );
189
  $form['tracking']['linktracking']['piwik_trackmailto'] = array(
190
    '#type' => 'checkbox',
191
    '#title' => t('Track clicks on mailto links'),
192
    '#default_value' => variable_get('piwik_trackmailto', 1),
193
  );
194
  $form['tracking']['linktracking']['piwik_track'] = array(
195
    '#type' => 'checkbox',
196
    '#title' => t('Track clicks on outbound links and downloads (clicks on file links) for the following extensions'),
197
    '#default_value' => variable_get('piwik_track', 1),
198
  );
199
  $form['tracking']['linktracking']['piwik_trackfiles_extensions'] = array(
200
    '#title' => t('List of download file extensions'),
201
    '#title_display' => 'invisible',
202
    '#type' => 'textfield',
203
    '#default_value' => variable_get('piwik_trackfiles_extensions', PIWIK_TRACKFILES_EXTENSIONS),
204
    '#description' => t('A file extension list separated by the | character that will be tracked when clicked. Regular expressions are supported. For example: !extensions', array('!extensions' => PIWIK_TRACKFILES_EXTENSIONS)),
205
    '#maxlength' => 500,
206
    '#states' => array(
207
      'enabled' => array(
208
        ':input[name="piwik_track"]' => array('checked' => TRUE),
209
      ),
210
      # Note: Form required marker is not visible as title is invisible.
211
      'required' => array(
212
        ':input[name="piwik_track"]' => array('checked' => TRUE),
213
      ),
214
    ),
215
  );
216

  
217
  $colorbox_dependencies = '<div class="admin-requirements">';
218
  $colorbox_dependencies .= t('Requires: !module-list', array('!module-list' => (module_exists('colorbox') ? t('@module (<span class="admin-enabled">enabled</span>)', array('@module' => 'Colorbox')) : t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => 'Colorbox')))));
219
  $colorbox_dependencies .= '</div>';
220

  
221
  $form['tracking']['linktracking']['piwik_trackcolorbox'] = array(
222
    '#type' => 'checkbox',
223
    '#title' => t('Track content in colorbox modal dialogs'),
224
    '#default_value' => variable_get('piwik_trackcolorbox', 1),
225
    '#description' => t('Enable to track the content shown in colorbox modal windows.') . $colorbox_dependencies,
226
    '#disabled' => (module_exists('colorbox') ? FALSE : TRUE),
227
  );
228

  
229
  // Message specific configurations.
230
  $form['tracking']['messagetracking'] = array(
231
    '#type' => 'fieldset',
232
    '#title' => t('Messages'),
233
  );
234
  $form['tracking']['messagetracking']['piwik_trackmessages'] = array(
235
    '#type' => 'checkboxes',
236
    '#title' => t('Track messages of type'),
237
    '#default_value' => variable_get('piwik_trackmessages', array()),
238
    '#description' => t('This will track the selected message types shown to users. Tracking of form validation errors may help you identifying usability issues in your site. Every message is tracked as one individual event. Messages from excluded pages cannot be tracked.'),
239
    '#options' => array(
240
      'status' => t('Status message'),
241
      'warning' => t('Warning message'),
242
      'error' => t('Error message'),
243
    ),
244
  );
245

  
246
  $form['tracking']['search'] = array(
247
    '#type' => 'fieldset',
248
    '#title' => t('Search'),
249
  );
250

  
251
  $site_search_dependencies = '<div class="admin-requirements">';
252
  $site_search_dependencies .= t('Requires: !module-list', array('!module-list' => (module_exists('search') ? t('@module (<span class="admin-enabled">enabled</span>)', array('@module' => 'Search')) : t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => 'Search')))));
253
  $site_search_dependencies .= '</div>';
254

  
255
  $form['tracking']['search']['piwik_site_search'] = array(
256
    '#type' => 'checkbox',
257
    '#title' => t('Track internal search'),
258
    '#description' => t('If checked, internal search keywords are tracked.') . $site_search_dependencies,
259
    '#default_value' => variable_get('piwik_site_search', FALSE),
260
    '#disabled' => (module_exists('search') ? FALSE : TRUE),
261
  );
262

  
263
  // Privacy specific configurations.
264
  $form['tracking']['privacy'] = array(
265
    '#type' => 'fieldset',
266
    '#title' => t('Privacy'),
267
  );
268
  $form['tracking']['privacy']['piwik_privacy_donottrack'] = array(
269
    '#type' => 'checkbox',
270
    '#title' => t('Universal web tracking opt-out'),
271
    '#description' => t('If enabled and your Piwik server receives the <a href="http://donottrack.us/">Do-Not-Track</a> header from the client browser, the Piwik server will not track the user. Compliance with Do Not Track could be purely voluntary, enforced by industry self-regulation, or mandated by state or federal law. Please accept your visitors privacy. If they have opt-out from tracking and advertising, you should accept their personal decision.'),
272
    '#default_value' => variable_get('piwik_privacy_donottrack', 1),
273
  );
274

  
275
  // Piwik page title tree view settings.
276
  $form['page_title_hierarchy'] = array(
277
    '#type' => 'fieldset',
278
    '#title' => t('Page titles hierarchy'),
279
    '#description' => t('This functionality enables a dynamically expandable tree view of your site page titles in your Piwik statistics. See in Piwik statistics under <em>Actions</em> > <em>Page titles</em>.'),
280
    '#collapsible' => TRUE,
281
    '#collapsed' => FALSE,
282
  );
283
  $form['page_title_hierarchy']['piwik_page_title_hierarchy'] = array(
284
    '#type' => 'checkbox',
285
    '#title' => t("Show page titles as hierarchy like breadcrumbs"),
286
    '#description' => t('By default Piwik tracks the current page title and shows you a flat list of the most popular titles. This enables a breadcrumbs like tree view.'),
287
    '#default_value' => variable_get('piwik_page_title_hierarchy', FALSE),
288
  );
289
  $form['page_title_hierarchy']['piwik_page_title_hierarchy_exclude_home'] = array(
290
    '#type' => 'checkbox',
291
    '#title' => t('Hide home page from hierarchy'),
292
    '#description' => t('If enabled, the "Home" item will be removed from the hierarchy to flatten the structure in the Piwik statistics. Hits to the home page will still be counted, but for other pages the hierarchy will start at level Home+1.'),
293
    '#default_value' => variable_get('piwik_page_title_hierarchy_exclude_home', TRUE),
294
  );
295

  
296
  $form['piwik_custom_var'] = array(
297
    '#collapsible' => TRUE,
298
  	'#collapsed' => TRUE,
299
    '#description' => t('You can add Piwiks <a href="!custom_var_documentation">Custom Variables</a> here. These will be added to every page that Piwik tracking code appears on. Custom variable names and values are limited to 200 characters in length. Keep the names and values as short as possible and expect long values to get trimmed. You may use tokens in custom variable names and values. Global and user tokens are always available; on node pages, node tokens are also available.', array('!custom_var_documentation' => 'http://piwik.org/docs/custom-variables/')),
300
    '#theme' => 'piwik_admin_custom_var_table',
301
    '#title' => t('Custom variables'),
302
    '#tree' => TRUE,
303
    '#type' => 'fieldset',
304
  );
305

  
306
  $piwik_custom_vars = variable_get('piwik_custom_var', array());
307

  
308
  // Piwik supports up to 5 custom variables.
309
  for ($i = 1; $i < 6; $i++) {
310
    $form['piwik_custom_var']['slots'][$i]['slot'] = array(
311
      '#default_value' => $i,
312
      '#description' => t('Slot number'),
313
      '#disabled' => TRUE,
314
      '#size' => 1,
315
      '#title' => t('Custom variable slot #@slot', array('@slot' => $i)),
316
      '#title_display' => 'invisible',
317
      '#type' => 'textfield',
318
    );
319
    $form['piwik_custom_var']['slots'][$i]['name'] = array(
320
      '#default_value' => !empty($piwik_custom_vars['slots'][$i]['name']) ? $piwik_custom_vars['slots'][$i]['name'] : '',
321
      '#description' => t('The custom variable name.'),
322
      '#maxlength' => 100,
323
    	'#size' => 20,
324
      '#title' => t('Custom variable name #@slot', array('@slot' => $i)),
325
      '#title_display' => 'invisible',
326
      '#type' => 'textfield',
327
    );
328
    $form['piwik_custom_var']['slots'][$i]['value'] = array(
329
      '#default_value' => !empty($piwik_custom_vars['slots'][$i]['value']) ? $piwik_custom_vars['slots'][$i]['value'] : '',
330
      '#description' => t('The custom variable value.'),
331
      '#maxlength' => 255,
332
      '#title' => t('Custom variable value #@slot', array('@slot' => $i)),
333
      '#title_display' => 'invisible',
334
      '#type' => 'textfield',
335
      '#element_validate' => array('piwik_token_element_validate'),
336
      '#token_types' => array('node'),
337
    );
338
    if (module_exists('token')) {
339
      $form['piwik_custom_var']['slots'][$i]['value']['#element_validate'][] = 'token_element_validate';
340
    }
341
    $form['piwik_custom_var']['slots'][$i]['scope'] = array(
342
      '#default_value' => !empty($piwik_custom_vars['slots'][$i]['scope']) ? $piwik_custom_vars['slots'][$i]['scope'] : 'visit',
343
      '#description' => t('The scope for the custom variable.'),
344
      '#title' => t('Custom variable slot #@slot', array('@slot' => $i)),
345
      '#title_display' => 'invisible',
346
      '#type' => 'select',
347
      '#options' => array(
348
        'visit' => t('Visit'),
349
        'page' => t('Page'),
350
      ),
351
    );
352
  }
353

  
354
  $form['piwik_custom_var']['piwik_custom_var_description'] = array(
355
    '#type' => 'item',
356
    '#description' => t('You can supplement Piwiks\' basic IP address tracking of visitors by segmenting users based on custom variables. Make sure you will not associate (or permit any third party to associate) any data gathered from your websites (or such third parties\' websites) with any personally identifying information from any source as part of your use (or such third parties\' use) of the Piwik\' service.'),
357
  );
358
  $form['piwik_custom_var']['piwik_custom_var_token_tree'] = array(
359
    '#theme' => 'token_tree',
360
    '#token_types' => array('node'),
361
    '#dialog' => TRUE,
362
  );
363

  
364
  // Advanced feature configurations.
365
  $form['advanced'] = array(
366
    '#type' => 'fieldset',
367
    '#title' => t('Advanced settings'),
368
    '#collapsible' => TRUE,
369
    '#collapsed' => TRUE,
370
  );
371

  
372
  $form['advanced']['piwik_cache'] = array(
373
    '#type' => 'checkbox',
374
    '#title' => t('Locally cache tracking code file'),
375
    '#description' => t('If checked, the tracking code file is retrieved from your Piwik site and cached locally. It is updated daily to ensure updates to tracking code are reflected in the local copy.'),
376
    '#default_value' => variable_get('piwik_cache', 0),
377
  );
378

  
379
  // Allow for tracking of the originating node when viewing translation sets.
380
  if (module_exists('translation')) {
381
    $form['advanced']['piwik_translation_set'] = array(
382
      '#type' => 'checkbox',
383
      '#title' => t('Track translation sets as one unit'),
384
      '#description' => t('When a node is part of a translation set, record statistics for the originating node instead. This allows for a translation set to be treated as a single unit.'),
385
      '#default_value' => variable_get('piwik_translation_set', 0),
386
    );
387
  }
388

  
389
  // Code snippet settings.
390
  $user_access_add_js_snippets = !user_access('add JS snippets for piwik');
391
  $user_access_add_js_snippets_permission_warning = $user_access_add_js_snippets ? ' <em>' . t('This field has been disabled because you do not have sufficient permissions to edit it.') . '</em>' : '';
392
  $form['advanced']['codesnippet'] = array(
393
    '#type' => 'fieldset',
394
    '#title' => t('Custom JavaScript code'),
395
    '#collapsible' => TRUE,
396
    '#collapsed' => TRUE,
397
    '#description' => t('You can add custom Piwik <a href="@snippets">code snippets</a> here. These will be added to every page that Piwik appears on. <strong>Do not include the &lt;script&gt; tags</strong>, and always end your code with a semicolon (;).', array('@snippets' => 'http://piwik.org/docs/javascript-tracking/'))
398
  );
399
  $form['advanced']['codesnippet']['piwik_codesnippet_before'] = array(
400
    '#type' => 'textarea',
401
    '#title' => t('Code snippet (before)'),
402
    '#default_value' => variable_get('piwik_codesnippet_before', ''),
403
    '#disabled' => $user_access_add_js_snippets,
404
    '#rows' => 5,
405
    '#description' => t('Code in this textarea will be added <strong>before</strong> _paq.push(["trackPageView"]).')
406
  );
407
  $form['advanced']['codesnippet']['piwik_codesnippet_after'] = array(
408
    '#type' => 'textarea',
409
    '#title' => t('Code snippet (after)'),
410
    '#default_value' => variable_get('piwik_codesnippet_after', ''),
411
    '#disabled' => $user_access_add_js_snippets,
412
    '#rows' => 5,
413
    '#description' => t('Code in this textarea will be added <strong>after</strong> _paq.push(["trackPageView"]). This is useful if you\'d like to track a site in two accounts.')
414
  );
415

  
416
  $form['advanced']['piwik_js_scope'] = array(
417
    '#type' => 'select',
418
    '#title' => t('JavaScript scope'),
419
    '#description' => t("Piwik recommends adding the tracking code to the header for performance reasons."),
420
    '#options' => array(
421
      'footer' => t('Footer'),
422
      'header' => t('Header'),
423
    ),
424
    '#default_value' => variable_get('piwik_js_scope', 'header'),
425
  );
426

  
427
  return system_settings_form($form);
428
}
429

  
430
function piwik_admin_settings_form_validate($form, &$form_state) {
431
  // Custom variables validation.
432
  foreach ($form_state['values']['piwik_custom_var']['slots'] as $custom_var) {
433
    $form_state['values']['piwik_custom_var']['slots'][$custom_var['slot']]['name'] = trim($custom_var['name']);
434
    $form_state['values']['piwik_custom_var']['slots'][$custom_var['slot']]['value'] = trim($custom_var['value']);
435

  
436
    // Validate empty names/values.
437
    if (empty($custom_var['name']) && !empty($custom_var['value'])) {
438
      form_set_error("piwik_custom_var][slots][" . $custom_var['slot'] . "][name", t('The custom variable @slot-number requires a <em>Name</em> if a <em>Value</em> has been provided.', array('@slot-number' => $custom_var['slot'])));
439
    }
440
    elseif (!empty($custom_var['name']) && empty($custom_var['value'])) {
441
      form_set_error("piwik_custom_var][slots][" . $custom_var['slot'] . "][value", t('The custom variable @slot-number requires a <em>Value</em> if a <em>Name</em> has been provided.', array('@slot-number' => $custom_var['slot'])));
442
    }
443
  }
444

  
445
  // Trim some text area values.
446
  $form_state['values']['piwik_site_id'] = trim($form_state['values']['piwik_site_id']);
447
  $form_state['values']['piwik_pages'] = trim($form_state['values']['piwik_pages']);
448
  $form_state['values']['piwik_codesnippet_before'] = trim($form_state['values']['piwik_codesnippet_before']);
449
  $form_state['values']['piwik_codesnippet_after'] = trim($form_state['values']['piwik_codesnippet_after']);
450

  
451
  if (!preg_match('/^\d{1,}$/', $form_state['values']['piwik_site_id'])) {
452
    form_set_error('piwik_site_id', t('A valid Piwik site ID is an integer only.'));
453
  }
454

  
455
  $piwik_url = $form_state['values']['piwik_url_http'];
456
  if ('/' != drupal_substr($piwik_url, -1, 1)) {
457
    $piwik_url = $piwik_url . '/';
458
    $form_state['values']['piwik_url_http'] = $piwik_url;
459
  }
460
  $url = $piwik_url . 'piwik.php';
461
  $result = drupal_http_request($url);
462
  if ($result->code != 200 && $form_state['values']['piwik_url_skiperror'] == FALSE) {
463
    form_set_error('piwik_url_http', t('The validation of "@url" failed with error "@error" (HTTP code @code).', array('@url' => check_url($url), '@error' => $result->error, '@code' => $result->code)));
464
  }
465

  
466
  if (!empty($form_state['values']['piwik_url_https'])) {
467
    $piwik_url = $form_state['values']['piwik_url_https'];
468
    if ('/' != drupal_substr($piwik_url, -1, 1)) {
469
      $piwik_url = $piwik_url . '/';
470
      $form_state['values']['piwik_url_https'] = $piwik_url;
471
    }
472
    $url = $piwik_url . 'piwik.php';
473
    $result = drupal_http_request($url);
474
    if ($result->code != 200 && $form_state['values']['piwik_url_skiperror'] == FALSE) {
475
      form_set_error('piwik_url_https', t('The validation of "@url" failed with error "@error" (HTTP code @code).', array('@url' => check_url($url), '@error' => $result->error, '@code' => $result->code)));
476
    }
477
  }
478

  
479
  // Delete obsolete local cache file.
480
  if (empty($form_state['values']['piwik_cache']) && $form['advanced']['piwik_cache']['#default_value']) {
481
    piwik_clear_js_cache();
482
  }
483

  
484
  // This is for the Newbie's who cannot read a text area description.
485
  if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state['values']['piwik_codesnippet_before'])) {
486
    form_set_error('piwik_codesnippet_before', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
487
  }
488
  if (preg_match('/(.*)<\/?script(.*)>(.*)/i', $form_state['values']['piwik_codesnippet_after'])) {
489
    form_set_error('piwik_codesnippet_after', t('Do not include the &lt;script&gt; tags in the javascript code snippets.'));
490
  }
491
}
492

  
493
/**
494
 * Layout for the custom variables table in the admin settings form.
495
 *
496
 * @param array $variables
497
 *   An array contains the form elements.
498
 *
499
 * @return string
500
 *   The rendered output.
501
 */
502
function theme_piwik_admin_custom_var_table($variables) {
503
  $form = $variables['form'];
504

  
505
  $header = array(
506
    array('data' => t('Slot')),
507
    array('data' => t('Name')),
508
    array('data' => t('Value')),
509
    array('data' => t('Scope')),
510
  );
511

  
512
  $rows = array();
513
  foreach (element_children($form['slots']) as $key => $id) {
514
    $rows[] = array(
515
      'data' => array(
516
        drupal_render($form['slots'][$id]['slot']),
517
        drupal_render($form['slots'][$id]['name']),
518
        drupal_render($form['slots'][$id]['value']),
519
        drupal_render($form['slots'][$id]['scope']),
520
      ),
521
    );
522
  }
523

  
524
  $output = theme('table', array('header' => $header, 'rows' => $rows));
525
  $output .= drupal_render($form['piwik_custom_var_description']);
526
  $output .= drupal_render($form['piwik_custom_var_token_tree']);
527

  
528
  return $output;
529
}
530

  
531
/**
532
 * Validate a form element that should have tokens in it.
533
 *
534
 * For example:
535
 * @code
536
 * $form['my_node_text_element'] = array(
537
 *   '#type' => 'textfield',
538
 *   '#title' => t('Some text to token-ize that has a node context.'),
539
 *   '#default_value' => 'The title of this node is [node:title].',
540
 *   '#element_validate' => array('piwik_token_element_validate'),
541
 * );
542
 * @endcode
543
 */
544
function piwik_token_element_validate(&$element, &$form_state) {
545
  $value = isset($element['#value']) ? $element['#value'] : $element['#default_value'];
546

  
547
  if (!drupal_strlen($value)) {
548
    // Empty value needs no further validation since the element should depend
549
    // on using the '#required' FAPI property.
550
    return $element;
551
  }
552

  
553
  $tokens = token_scan($value);
554
  $invalid_tokens = _piwik_get_forbidden_tokens($tokens);
555
  if ($invalid_tokens) {
556
    form_error($element, t('The %element-title is using the following forbidden tokens with personal identifying information: @invalid-tokens.', array('%element-title' => $element['#title'], '@invalid-tokens' => implode(', ', $invalid_tokens))));
557
  }
558

  
559
  return $element;
560
}
561

  
562
/**
563
 * @param array $value
564
 *   An array of token values.
565
 *
566
 * @return array
567
 *   A unique array of invalid tokens.
568
 */
569
function _piwik_get_forbidden_tokens($value) {
570
  $invalid_tokens = array();
571
  $value_tokens = is_string($value) ? token_scan($value) : $value;
572

  
573
  foreach ($value_tokens as $type => $tokens) {
574
    if (array_filter($tokens, '_piwik_contains_forbidden_token')) {
575
      $invalid_tokens = array_merge($invalid_tokens, array_values($tokens));
576
    }
577
  }
578

  
579
  array_unique($invalid_tokens);
580
  return $invalid_tokens;
581
}
582

  
583
/**
584
 * Validate if a string contains forbidden tokens not allowed by privacy rules.
585
 *
586
 * @param string $token_string
587
 *   A string with one or more tokens to be validated.
588
 *
589
 * @return boolean
590
 *   TRUE if blacklisted token has been found, otherwise FALSE.
591
 */
592
function _piwik_contains_forbidden_token($token_string) {
593
  // List of strings in tokens with personal identifying information not allowed
594
  // for privacy reasons. See section 8.1 of the Google Analytics terms of use
595
  // for more detailed information.
596
  //
597
  // This list can never ever be complete. For this reason it tries to use a
598
  // regex and may kill a few other valid tokens, but it's the only way to
599
  // protect users as much as possible from admins with illegal ideas.
600
  //
601
  // User tokens are not prefixed with colon to catch 'current-user' and 'user'.
602
  //
603
  // TODO: If someone have better ideas, share them, please!
604
  $token_blacklist = array(
605
    ':author]',
606
    ':author:edit-url]',
607
    ':author:url]',
608
    ':author:path]',
609
    ':current-user]',
610
    ':current-user:original]',
611
    ':fid]',
612
    ':mail]',
613
    ':name]',
614
    ':uid]',
615
    ':one-time-login-url]',
616
    ':owner]',
617
    ':owner:cancel-url]',
618
    ':owner:edit-url]',
619
    ':owner:url]',
620
    ':owner:path]',
621
    'user:cancel-url]',
622
    'user:edit-url]',
623
    'user:url]',
624
    'user:path]',
625
    'user:picture]',
626
    // addressfield_tokens.module
627
    ':first-name]',
628
    ':last-name]',
629
    ':name-line]',
630
    ':mc-address]',
631
    ':thoroughfare]',
632
    ':premise]',
633
    // realname.module
634
    ':name-raw]',
635
    // token.module
636
    ':ip-address]',
637
  );
638

  
639
  return preg_match('/' . implode('|', array_map('preg_quote', $token_blacklist)) . '/i', $token_string);
640
}
drupal7/sites/all/modules/piwik/piwik.admin.js
1
(function ($) {
2

  
3
/**
4
 * Provide the summary information for the tracking settings vertical tabs.
5
 */
6
Drupal.behaviors.trackingSettingsSummary = {
7
  attach: function (context) {
8
    // Make sure this behavior is processed only if drupalSetSummary is defined.
9
    if (typeof jQuery.fn.drupalSetSummary == 'undefined') {
10
      return;
11
    }
12

  
13
    $('fieldset#edit-domain-tracking', context).drupalSetSummary(function (context) {
14
      var $radio = $('input[name="piwik_domain_mode"]:checked', context);
15
      if ($radio.val() == 0) {
16
        return Drupal.t('A single domain');
17
      }
18
      else if ($radio.val() == 1) {
19
        return Drupal.t('One domain with multiple subdomains');
20
      }
21
    });
22

  
23
    $('fieldset#edit-page-vis-settings', context).drupalSetSummary(function (context) {
24
      var $radio = $('input[name="piwik_visibility_pages"]:checked', context);
25
      if ($radio.val() == 0) {
26
        if (!$('textarea[name="piwik_pages"]', context).val()) {
27
          return Drupal.t('Not restricted');
28
        }
29
        else {
30
          return Drupal.t('All pages with exceptions');
31
        }
32
      }
33
      else {
34
        return Drupal.t('Restricted to certain pages');
35
      }
36
    });
37

  
38
    $('fieldset#edit-role-vis-settings', context).drupalSetSummary(function (context) {
39
      var vals = [];
40
      $('input[type="checkbox"]:checked', context).each(function () {
41
        vals.push($.trim($(this).next('label').text()));
42
      });
43
      if (!vals.length) {
44
        return Drupal.t('Not restricted');
45
      }
46
      else if ($('input[name="piwik_visibility_roles"]:checked', context).val() == 1) {
47
        return Drupal.t('Excepted: @roles', {'@roles' : vals.join(', ')});
48
      }
49
      else {
50
        return vals.join(', ');
51
      }
52
    });
53

  
54
    $('fieldset#edit-user-vis-settings', context).drupalSetSummary(function (context) {
55
      var $radio = $('input[name="piwik_custom"]:checked', context);
56
      if ($radio.val() == 0) {
57
        return Drupal.t('Not customizable');
58
      }
59
      else if ($radio.val() == 1) {
60
        return Drupal.t('On by default with opt out');
61
      }
62
      else {
63
        return Drupal.t('Off by default with opt in');
64
      }
65
    });
66

  
67
    $('fieldset#edit-linktracking', context).drupalSetSummary(function (context) {
68
      var vals = [];
69
      if ($('input#edit-piwik-trackmailto', context).is(':checked')) {
70
        vals.push(Drupal.t('Mailto links'));
71
      }
72
      if ($('input#edit-piwik-track', context).is(':checked')) {
73
        vals.push(Drupal.t('Outbound links'));
74
        vals.push(Drupal.t('Downloads'));
75
      }
76
      if ($('input#edit-piwik-trackcolorbox', context).is(':checked')) {
77
        vals.push(Drupal.t('Colorbox'));
78
      }
79
      if (!vals.length) {
80
        return Drupal.t('Not tracked');
81
      }
82
      return Drupal.t('@items enabled', {'@items' : vals.join(', ')});
83
    });
84

  
85
    $('fieldset#edit-messagetracking', context).drupalSetSummary(function (context) {
86
      var vals = [];
87
      $('input[type="checkbox"]:checked', context).each(function () {
88
        vals.push($.trim($(this).next('label').text()));
89
      });
90
      if (!vals.length) {
91
        return Drupal.t('Not tracked');
92
      }
93
      return Drupal.t('@items enabled', {'@items' : vals.join(', ')});
94
    });
95

  
96
    $('fieldset#edit-search', context).drupalSetSummary(function (context) {
97
      var vals = [];
98
      if ($('input#edit-piwik-site-search', context).is(':checked')) {
99
        vals.push(Drupal.t('Site search'));
100
      }
101
      if (!vals.length) {
102
        return Drupal.t('Not tracked');
103
      }
104
      return Drupal.t('@items enabled', {'@items' : vals.join(', ')});
105
    });
106

  
107
    $('fieldset#edit-privacy', context).drupalSetSummary(function (context) {
108
      var vals = [];
109
      if ($('input#edit-piwik-privacy-donottrack', context).is(':checked')) {
110
        vals.push(Drupal.t('Universal web tracking opt-out'));
111
      }
112
      if (!vals.length) {
113
        return Drupal.t('No privacy');
114
      }
115
      return Drupal.t('@items enabled', {'@items' : vals.join(', ')});
116
    });
117
  }
118
};
119

  
120
})(jQuery);
drupal7/sites/all/modules/piwik/piwik.info
1
name = "Piwik Web Analytics"
2
description = Adds Piwik javascript tracking code to all your site's pages.
3
core = 7.x
4
package = Statistics
5
configure = admin/config/system/piwik
6
files[] = piwik.test
7
test_dependencies[] = token
8
dependencies[] = matomo
9

  
10
; Information added by Drupal.org packaging script on 2018-06-08
11
version = "7.x-2.12"
12
core = "7.x"
13
project = "piwik"
14
datestamp = "1528483689"
drupal7/sites/all/modules/piwik/piwik.install
1
<?php
2

  
3
/**
4
 * @file
5
 * Installation file for Piwik - Web analytics module.
6
 */
7

  
8
function piwik_install() {
9
  // Remove tracking from all administrative pages, see http://drupal.org/node/34970.
10
  variable_set('piwik_visibility_roles', 0);
11
  variable_set('piwik_visibility_pages', 0);
12
  $pages = array(
13
    'admin',
14
    'admin/*',
15
    'batch',
16
    'node/add*',
17
    'node/*/*',
18
    'user/*/*',
19
  );
20
  variable_set('piwik_pages', implode("\n", $pages));
21
}
22

  
23
function piwik_uninstall() {
24
  variable_del('piwik_cache');
25
  variable_del('piwik_codesnippet_before');
26
  variable_del('piwik_codesnippet_after');
27
  variable_del('piwik_custom');
28
  variable_del('piwik_custom_var');
29
  variable_del('piwik_domain_mode');
30
  variable_del('piwik_js_scope');
31
  variable_del('piwik_last_cache');
32
  variable_del('piwik_page_title_hierarchy');
33
  variable_del('piwik_page_title_hierarchy_exclude_home');
34
  variable_del('piwik_pages');
35
  variable_del('piwik_privacy_donottrack');
36
  variable_del('piwik_roles');
37
  variable_del('piwik_site_id');
38
  variable_del('piwik_site_search');
39
  variable_del('piwik_trackcolorbox');
40
  variable_del('piwik_trackmailto');
... Ce différentiel a été tronqué car il excède la taille maximale pouvant être affichée.

Formats disponibles : Unified diff