Version Description
- Google Authentication now happens using OAuth. The requests have become signed as an extra security measure and tokens have become more stable, as opposed to the prior tokens used with AuthSub.
- Added support for cross-domain tracking.
- Fixed various small bugs.
Download this release
Release Info
Developer | joostdevalk |
Plugin | Google Analytics for WordPress by MonsterInsights |
Version | 4.2 |
Comparing to | |
See all releases |
Code changes from version 4.1.3 to 4.2
- googleanalytics.php +1569 -1500
- images/facebook-icon.png +0 -0
- images/google-plus-icon.png +0 -0
- images/twitter-icon.png +0 -0
- readme.txt +335 -329
- wp-gdata/OAuth.php +895 -0
- wp-gdata/wp-gdata.php +105 -0
- yst_plugin_tools.css +90 -75
- yst_plugin_tools.php +266 -256
googleanalytics.php
CHANGED
@@ -1,1500 +1,1569 @@
|
|
1 |
-
<?php
|
2 |
-
/*
|
3 |
-
Plugin Name: Google Analytics for WordPress
|
4 |
-
Plugin URI: http://yoast.com/wordpress/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=google-analytics-for-wordpress&utm_content=
|
5 |
-
Description: This plugin makes it simple to add Google Analytics to your WordPress blog, adding lots of features, eg. custom variables and automatic clickout and download tracking.
|
6 |
-
Author: Joost de Valk
|
7 |
-
Version: 4.
|
8 |
-
Requires at least: 2.8
|
9 |
-
Author URI: http://yoast.com/
|
10 |
-
License: GPL
|
11 |
-
*/
|
12 |
-
|
13 |
-
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics
|
14 |
-
|
15 |
-
define('GAWP_VERSION', '4.
|
16 |
-
|
17 |
-
/*
|
18 |
-
* Admin User Interface
|
19 |
-
*/
|
20 |
-
|
21 |
-
if ( is_admin() && ( !defined('DOING_AJAX') || !DOING_AJAX ) && !class_exists( 'GA_Admin' ) ) {
|
22 |
-
|
23 |
-
require_once plugin_dir_path( __FILE__ ) . 'yst_plugin_tools.php';
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
var $
|
29 |
-
var $
|
30 |
-
var $
|
31 |
-
var $
|
32 |
-
var $
|
33 |
-
var $
|
34 |
-
var $
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
add_action('
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
//
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
jQuery(
|
99 |
-
|
100 |
-
|
101 |
-
jQuery(
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
jQuery('#
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
jQuery('#
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
jQuery('
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
jQuery('#
|
147 |
-
jQuery('
|
148 |
-
jQuery('.
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
$
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
$output
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
}
|
232 |
-
|
233 |
-
$
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
$options['
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
require_once plugin_dir_path(__FILE__).'xmlparser.php';
|
311 |
-
if (file_exists(ABSPATH.'wp-includes/class-http.php'))
|
312 |
-
require_once(ABSPATH.'wp-includes/class-http.php');
|
313 |
-
|
314 |
-
if (!isset($options['ga_api_responses'][$token])) {
|
315 |
-
$options['ga_api_responses'] = array();
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
$
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
-
|
337 |
-
$
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
$
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
$
|
378 |
-
$
|
379 |
-
|
380 |
-
|
381 |
-
$
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
$line
|
397 |
-
$line .= '
|
398 |
-
|
399 |
-
$line
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
$
|
405 |
-
|
406 |
-
|
407 |
-
|
408 |
-
'
|
409 |
-
|
410 |
-
'
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
|
420 |
-
|
421 |
-
|
422 |
-
|
423 |
-
|
424 |
-
|
425 |
-
|
426 |
-
|
427 |
-
|
428 |
-
|
429 |
-
|
430 |
-
|
431 |
-
|
432 |
-
|
433 |
-
|
434 |
-
|
435 |
-
|
436 |
-
|
437 |
-
|
438 |
-
|
439 |
-
|
440 |
-
|
441 |
-
|
442 |
-
|
443 |
-
|
444 |
-
'
|
445 |
-
'
|
446 |
-
|
447 |
-
|
448 |
-
|
449 |
-
|
450 |
-
'
|
451 |
-
'
|
452 |
-
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
457 |
-
|
458 |
-
|
459 |
-
$
|
460 |
-
|
461 |
-
|
462 |
-
|
463 |
-
|
464 |
-
|
465 |
-
|
466 |
-
'
|
467 |
-
'
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
'
|
473 |
-
'
|
474 |
-
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
'
|
479 |
-
'
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
|
484 |
-
'
|
485 |
-
'
|
486 |
-
|
487 |
-
|
488 |
-
|
489 |
-
|
490 |
-
'
|
491 |
-
'
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
|
496 |
-
'
|
497 |
-
'
|
498 |
-
|
499 |
-
|
500 |
-
|
501 |
-
|
502 |
-
|
503 |
-
|
504 |
-
|
505 |
-
|
506 |
-
$
|
507 |
-
|
508 |
-
|
509 |
-
|
510 |
-
|
511 |
-
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
'
|
516 |
-
'
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
'
|
527 |
-
'
|
528 |
-
|
529 |
-
|
530 |
-
|
531 |
-
|
532 |
-
'
|
533 |
-
'
|
534 |
-
|
535 |
-
|
536 |
-
|
537 |
-
|
538 |
-
|
539 |
-
|
540 |
-
|
541 |
-
|
542 |
-
|
543 |
-
|
544 |
-
|
545 |
-
|
546 |
-
|
547 |
-
|
548 |
-
|
549 |
-
|
550 |
-
|
551 |
-
|
552 |
-
|
553 |
-
|
554 |
-
|
555 |
-
|
556 |
-
|
557 |
-
|
558 |
-
|
559 |
-
|
560 |
-
'
|
561 |
-
'
|
562 |
-
|
563 |
-
|
564 |
-
|
565 |
-
|
566 |
-
'
|
567 |
-
'
|
568 |
-
|
569 |
-
|
570 |
-
|
571 |
-
|
572 |
-
'
|
573 |
-
'
|
574 |
-
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
'
|
579 |
-
'
|
580 |
-
|
581 |
-
|
582 |
-
|
583 |
-
|
584 |
-
'desc' => '
|
585 |
-
|
586 |
-
|
587 |
-
|
588 |
-
'
|
589 |
-
'
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
-
|
594 |
-
|
595 |
-
'
|
596 |
-
'
|
597 |
-
'
|
598 |
-
|
599 |
-
|
600 |
-
|
601 |
-
'
|
602 |
-
'
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
'
|
607 |
-
|
608 |
-
|
609 |
-
|
610 |
-
|
611 |
-
'
|
612 |
-
|
613 |
-
|
614 |
-
'
|
615 |
-
);
|
616 |
-
$rows[] = array(
|
617 |
-
'id' => '
|
618 |
-
'label' => '
|
619 |
-
'desc' => '
|
620 |
-
'content' => $this->checkbox('
|
621 |
-
);
|
622 |
-
$rows[] = array(
|
623 |
-
'id' => '
|
624 |
-
'label' => '
|
625 |
-
'
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
'
|
630 |
-
'
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
$rows[] = array(
|
639 |
-
'id' => '
|
640 |
-
'label' => '
|
641 |
-
'desc' => '
|
642 |
-
'content' => $this->
|
643 |
-
);
|
644 |
-
$rows[] = array(
|
645 |
-
'id' => '
|
646 |
-
'label' => '
|
647 |
-
'desc' => '
|
648 |
-
'content' => $this->
|
649 |
-
);
|
650 |
-
$
|
651 |
-
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
|
656 |
-
|
657 |
-
|
658 |
-
|
659 |
-
|
660 |
-
|
661 |
-
|
662 |
-
|
663 |
-
|
664 |
-
|
665 |
-
|
666 |
-
|
667 |
-
|
668 |
-
|
669 |
-
|
670 |
-
|
671 |
-
|
672 |
-
|
673 |
-
|
674 |
-
|
675 |
-
|
676 |
-
$
|
677 |
-
|
678 |
-
|
679 |
-
'
|
680 |
-
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
|
685 |
-
|
686 |
-
|
687 |
-
|
688 |
-
|
689 |
-
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
)
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
719 |
-
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
-
|
724 |
-
|
725 |
-
|
726 |
-
|
727 |
-
|
728 |
-
|
729 |
-
|
730 |
-
|
731 |
-
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
|
736 |
-
|
737 |
-
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
-
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
|
766 |
-
|
767 |
-
|
768 |
-
|
769 |
-
'
|
770 |
-
'
|
771 |
-
'
|
772 |
-
'
|
773 |
-
'
|
774 |
-
'
|
775 |
-
'
|
776 |
-
'
|
777 |
-
'
|
778 |
-
'
|
779 |
-
'
|
780 |
-
'
|
781 |
-
'
|
782 |
-
'
|
783 |
-
'
|
784 |
-
'
|
785 |
-
'
|
786 |
-
|
787 |
-
|
788 |
-
|
789 |
-
|
790 |
-
|
791 |
-
|
792 |
-
|
793 |
-
|
794 |
-
|
795 |
-
|
796 |
-
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
|
803 |
-
|
804 |
-
|
805 |
-
|
806 |
-
|
807 |
-
|
808 |
-
|
809 |
-
|
810 |
-
|
811 |
-
|
812 |
-
|
813 |
-
|
814 |
-
|
815 |
-
|
816 |
-
|
817 |
-
|
818 |
-
|
819 |
-
|
820 |
-
|
821 |
-
|
822 |
-
|
823 |
-
|
824 |
-
|
825 |
-
|
826 |
-
if (
|
827 |
-
|
828 |
-
|
829 |
-
|
830 |
-
|
831 |
-
|
832 |
-
|
833 |
-
|
834 |
-
|
835 |
-
|
836 |
-
|
837 |
-
|
838 |
-
|
839 |
-
$
|
840 |
-
|
841 |
-
|
842 |
-
|
843 |
-
|
844 |
-
|
845 |
-
|
846 |
-
|
847 |
-
|
848 |
-
|
849 |
-
|
850 |
-
|
851 |
-
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
|
867 |
-
|
868 |
-
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
|
878 |
-
|
879 |
-
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
|
887 |
-
|
888 |
-
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
|
921 |
-
|
922 |
-
|
923 |
-
|
924 |
-
|
925 |
-
|
926 |
-
|
927 |
-
|
928 |
-
|
929 |
-
|
930 |
-
|
931 |
-
|
932 |
-
|
933 |
-
|
934 |
-
|
935 |
-
|
936 |
-
|
937 |
-
|
938 |
-
|
939 |
-
|
940 |
-
$
|
941 |
-
|
942 |
-
|
943 |
-
|
944 |
-
|
945 |
-
}
|
946 |
-
} else {
|
947 |
-
$
|
948 |
-
|
949 |
-
|
950 |
-
|
951 |
-
|
952 |
-
|
953 |
-
|
954 |
-
|
955 |
-
|
956 |
-
|
957 |
-
|
958 |
-
|
959 |
-
|
960 |
-
|
961 |
-
|
962 |
-
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
|
968 |
-
|
969 |
-
|
970 |
-
|
971 |
-
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
|
982 |
-
|
983 |
-
|
984 |
-
|
985 |
-
|
986 |
-
|
987 |
-
|
988 |
-
|
989 |
-
|
990 |
-
|
991 |
-
|
992 |
-
|
993 |
-
|
994 |
-
|
995 |
-
|
996 |
-
|
997 |
-
|
998 |
-
|
999 |
-
|
1000 |
-
}
|
1001 |
-
|
1002 |
-
|
1003 |
-
|
1004 |
-
|
1005 |
-
|
1006 |
-
|
1007 |
-
|
1008 |
-
|
1009 |
-
|
1010 |
-
|
1011 |
-
|
1012 |
-
|
1013 |
-
|
1014 |
-
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
|
1019 |
-
|
1020 |
-
|
1021 |
-
|
1022 |
-
|
1023 |
-
|
1024 |
-
|
1025 |
-
|
1026 |
-
|
1027 |
-
|
1028 |
-
|
1029 |
-
|
1030 |
-
|
1031 |
-
|
1032 |
-
|
1033 |
-
|
1034 |
-
|
1035 |
-
|
1036 |
-
|
1037 |
-
|
1038 |
-
|
1039 |
-
|
1040 |
-
|
1041 |
-
|
1042 |
-
|
1043 |
-
|
1044 |
-
|
1045 |
-
|
1046 |
-
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
1054 |
-
|
1055 |
-
|
1056 |
-
|
1057 |
-
|
1058 |
-
|
1059 |
-
|
1060 |
-
|
1061 |
-
|
1062 |
-
|
1063 |
-
|
1064 |
-
|
1065 |
-
|
1066 |
-
|
1067 |
-
|
1068 |
-
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
|
1074 |
-
|
1075 |
-
|
1076 |
-
|
1077 |
-
|
1078 |
-
|
1079 |
-
|
1080 |
-
|
1081 |
-
|
1082 |
-
|
1083 |
-
|
1084 |
-
|
1085 |
-
|
1086 |
-
|
1087 |
-
|
1088 |
-
|
1089 |
-
|
1090 |
-
|
1091 |
-
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
1096 |
-
|
1097 |
-
|
1098 |
-
|
1099 |
-
|
1100 |
-
|
1101 |
-
|
1102 |
-
|
1103 |
-
|
1104 |
-
|
1105 |
-
|
1106 |
-
|
1107 |
-
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
1111 |
-
|
1112 |
-
|
1113 |
-
|
1114 |
-
|
1115 |
-
|
1116 |
-
|
1117 |
-
|
1118 |
-
|
1119 |
-
|
1120 |
-
|
1121 |
-
|
1122 |
-
|
1123 |
-
|
1124 |
-
|
1125 |
-
|
1126 |
-
|
1127 |
-
|
1128 |
-
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
1136 |
-
|
1137 |
-
|
1138 |
-
|
1139 |
-
|
1140 |
-
|
1141 |
-
|
1142 |
-
|
1143 |
-
|
1144 |
-
$
|
1145 |
-
}
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
1152 |
-
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
1159 |
-
|
1160 |
-
|
1161 |
-
|
1162 |
-
|
1163 |
-
|
1164 |
-
|
1165 |
-
|
1166 |
-
|
1167 |
-
|
1168 |
-
|
1169 |
-
|
1170 |
-
|
1171 |
-
|
1172 |
-
|
1173 |
-
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
-
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
-
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
$
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
|
1250 |
-
|
1251 |
-
|
1252 |
-
|
1253 |
-
|
1254 |
-
|
1255 |
-
|
1256 |
-
|
1257 |
-
|
1258 |
-
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
}
|
1270 |
-
$
|
1271 |
-
|
1272 |
-
|
1273 |
-
|
1274 |
-
|
1275 |
-
|
1276 |
-
|
1277 |
-
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
if (
|
1282 |
-
|
1283 |
-
|
1284 |
-
|
1285 |
-
$
|
1286 |
-
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
-
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
|
1295 |
-
|
1296 |
-
|
1297 |
-
$
|
1298 |
-
|
1299 |
-
|
1300 |
-
|
1301 |
-
|
1302 |
-
|
1303 |
-
|
1304 |
-
|
1305 |
-
|
1306 |
-
|
1307 |
-
|
1308 |
-
|
1309 |
-
|
1310 |
-
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
1314 |
-
|
1315 |
-
|
1316 |
-
|
1317 |
-
$
|
1318 |
-
|
1319 |
-
|
1320 |
-
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
1326 |
-
|
1327 |
-
|
1328 |
-
|
1329 |
-
|
1330 |
-
|
1331 |
-
$
|
1332 |
-
|
1333 |
-
|
1334 |
-
|
1335 |
-
$
|
1336 |
-
|
1337 |
-
$
|
1338 |
-
}
|
1339 |
-
|
1340 |
-
|
1341 |
-
|
1342 |
-
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
-
|
1353 |
-
|
1354 |
-
|
1355 |
-
|
1356 |
-
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
1361 |
-
|
1362 |
-
|
1363 |
-
|
1364 |
-
|
1365 |
-
|
1366 |
-
|
1367 |
-
|
1368 |
-
|
1369 |
-
|
1370 |
-
|
1371 |
-
|
1372 |
-
|
1373 |
-
|
1374 |
-
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
1387 |
-
|
1388 |
-
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
$
|
1410 |
-
}
|
1411 |
-
|
1412 |
-
|
1413 |
-
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
1426 |
-
|
1427 |
-
|
1428 |
-
|
1429 |
-
|
1430 |
-
|
1431 |
-
|
1432 |
-
|
1433 |
-
|
1434 |
-
}
|
1435 |
-
|
1436 |
-
|
1437 |
-
|
1438 |
-
function
|
1439 |
-
$
|
1440 |
-
|
1441 |
-
|
1442 |
-
|
1443 |
-
|
1444 |
-
|
1445 |
-
|
1446 |
-
$
|
1447 |
-
|
1448 |
-
|
1449 |
-
|
1450 |
-
|
1451 |
-
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
|
1459 |
-
|
1460 |
-
|
1461 |
-
|
1462 |
-
|
1463 |
-
|
1464 |
-
|
1465 |
-
|
1466 |
-
|
1467 |
-
|
1468 |
-
|
1469 |
-
|
1470 |
-
|
1471 |
-
|
1472 |
-
|
1473 |
-
|
1474 |
-
|
1475 |
-
|
1476 |
-
|
1477 |
-
|
1478 |
-
|
1479 |
-
|
1480 |
-
|
1481 |
-
|
1482 |
-
|
1483 |
-
|
1484 |
-
|
1485 |
-
|
1486 |
-
|
1487 |
-
|
1488 |
-
|
1489 |
-
|
1490 |
-
|
1491 |
-
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
-
|
1496 |
-
|
1497 |
-
if (
|
1498 |
-
|
1499 |
-
|
1500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Plugin Name: Google Analytics for WordPress
|
4 |
+
Plugin URI: http://yoast.com/wordpress/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=google-analytics-for-wordpress&utm_content=v420
|
5 |
+
Description: This plugin makes it simple to add Google Analytics to your WordPress blog, adding lots of features, eg. custom variables and automatic clickout and download tracking.
|
6 |
+
Author: Joost de Valk
|
7 |
+
Version: 4.2
|
8 |
+
Requires at least: 2.8
|
9 |
+
Author URI: http://yoast.com/
|
10 |
+
License: GPL
|
11 |
+
*/
|
12 |
+
|
13 |
+
// This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics
|
14 |
+
|
15 |
+
define('GAWP_VERSION', '4.2');
|
16 |
+
|
17 |
+
/*
|
18 |
+
* Admin User Interface
|
19 |
+
*/
|
20 |
+
|
21 |
+
if ( is_admin() && ( !defined('DOING_AJAX') || !DOING_AJAX ) && !class_exists( 'GA_Admin' ) ) {
|
22 |
+
|
23 |
+
require_once plugin_dir_path( __FILE__ ) . 'yst_plugin_tools.php';
|
24 |
+
require_once plugin_dir_path( __FILE__ ) . '/wp-gdata/wp-gdata.php';
|
25 |
+
|
26 |
+
class GA_Admin extends Yoast_GA_Plugin_Admin {
|
27 |
+
|
28 |
+
var $hook = 'google-analytics-for-wordpress';
|
29 |
+
var $filename = 'google-analytics-for-wordpress/googleanalytics.php';
|
30 |
+
var $longname = 'Google Analytics Configuration';
|
31 |
+
var $shortname = 'Google Analytics';
|
32 |
+
var $ozhicon = 'images/chart_curve.png';
|
33 |
+
var $optionname = 'Yoast_Google_Analytics';
|
34 |
+
var $homepage = 'http://yoast.com/wordpress/google-analytics/';
|
35 |
+
var $toc = '';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* PHP4 Constructor
|
39 |
+
*/
|
40 |
+
function GA_Admin() {
|
41 |
+
$this->__construct();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Constructur, load all required stuff.
|
46 |
+
*/
|
47 |
+
function __construct() {
|
48 |
+
$this->upgrade();
|
49 |
+
|
50 |
+
$this->plugin_url = plugins_url( '', __FILE__ ).'/';
|
51 |
+
|
52 |
+
// Register the settings page
|
53 |
+
add_action( 'admin_menu', array(&$this, 'register_settings_page') );
|
54 |
+
|
55 |
+
// Register the contextual help for the settings page
|
56 |
+
add_action( 'contextual_help', array(&$this, 'plugin_help'), 10, 3 );
|
57 |
+
|
58 |
+
// Give the settings page a nice icon in Ozh's menu
|
59 |
+
add_filter( 'ozh_adminmenu_icon', array(&$this, 'add_ozh_adminmenu_icon' ) );
|
60 |
+
|
61 |
+
// Give the plugin a settings link in the plugin overview
|
62 |
+
add_filter( 'plugin_action_links', array(&$this, 'add_action_link'), 10, 2 );
|
63 |
+
|
64 |
+
// Print Scripts and Styles
|
65 |
+
add_action('admin_print_scripts', array(&$this, 'config_page_scripts') );
|
66 |
+
add_action('admin_print_styles', array(&$this, 'config_page_styles') );
|
67 |
+
|
68 |
+
// Setup the dashboard news widget
|
69 |
+
add_action('wp_dashboard_setup', array(&$this, 'widget_setup') );
|
70 |
+
|
71 |
+
// Print stuff in the settings page's head
|
72 |
+
add_action('admin_head', array(&$this, 'config_page_head') );
|
73 |
+
|
74 |
+
// Drop a warning on each page of the admin when Google Analytics hasn't been configured
|
75 |
+
add_action('admin_footer', array(&$this, 'warning') );
|
76 |
+
|
77 |
+
// Save settings
|
78 |
+
// TODO: replace with Options API
|
79 |
+
add_action('admin_init', array(&$this, 'save_settings') );
|
80 |
+
|
81 |
+
// Authenticate
|
82 |
+
add_action('admin_init', array(&$this, 'authenticate') );
|
83 |
+
}
|
84 |
+
|
85 |
+
function config_page_head() {
|
86 |
+
global $current_screen;
|
87 |
+
if ( 'settings_page_'.$this->hook == $current_screen->id ) {
|
88 |
+
$options = get_option( $this->optionname );
|
89 |
+
if (!empty($options['uastring'])) {
|
90 |
+
$uastring = $options['uastring'];
|
91 |
+
} else {
|
92 |
+
$uastring = '';
|
93 |
+
}
|
94 |
+
|
95 |
+
?>
|
96 |
+
<script type="text/javascript">
|
97 |
+
function makeSublist(parent,child,childVal) {
|
98 |
+
jQuery("body").append("<select style='display:none' id='"+parent+child+"'></select>");
|
99 |
+
jQuery('#'+parent+child).html(jQuery("#"+child+" option"));
|
100 |
+
|
101 |
+
var parentValue = jQuery('#'+parent).val();
|
102 |
+
jQuery('#'+child).html(jQuery("#"+parent+child+" .sub_"+parentValue).clone());
|
103 |
+
|
104 |
+
childVal = (typeof childVal == "undefined")? "" : childVal ;
|
105 |
+
jQuery("#"+child).val(childVal).attr('selected','selected');
|
106 |
+
|
107 |
+
jQuery('#'+parent).change(function(){
|
108 |
+
var parentValue = jQuery('#'+parent).val();
|
109 |
+
jQuery('#'+child).html(jQuery("#"+parent+child+" .sub_"+parentValue).clone());
|
110 |
+
jQuery('#'+child).trigger("change");
|
111 |
+
jQuery('#'+child).focus();
|
112 |
+
});
|
113 |
+
}
|
114 |
+
jQuery(document).ready(function(){
|
115 |
+
makeSublist('ga_account', 'uastring_sel', '<?php echo $uastring; ?>');
|
116 |
+
jQuery('#position').change(function(){
|
117 |
+
if (jQuery('#position').val() == 'header') {
|
118 |
+
jQuery('#position_header').css("display","block");
|
119 |
+
jQuery('#position_manual').css("display","none");
|
120 |
+
} else {
|
121 |
+
jQuery('#position_header').css("display","none");
|
122 |
+
jQuery('#position_manual').css("display","block");
|
123 |
+
}
|
124 |
+
}).change();
|
125 |
+
jQuery('#switchtomanual').change(function() {
|
126 |
+
if ( jQuery('#switchtomanual').is(':checked') ) {
|
127 |
+
jQuery('#uastring_manual').css('display','block');
|
128 |
+
jQuery('#uastring_automatic').css('display','none');
|
129 |
+
} else {
|
130 |
+
jQuery('#uastring_manual').css('display','none');
|
131 |
+
jQuery('#uastring_automatic').css('display','block');
|
132 |
+
}
|
133 |
+
}).change();
|
134 |
+
jQuery('#trackoutbound').change(function(){
|
135 |
+
if ( jQuery('#trackoutbound').is(':checked') ) {
|
136 |
+
jQuery('#internallinktracking').css("display","block");
|
137 |
+
jQuery('.internallinktracking').css("display","list-item");
|
138 |
+
} else {
|
139 |
+
jQuery('#internallinktracking').css("display","none");
|
140 |
+
jQuery('.internallinktracking').css("display","none");
|
141 |
+
}
|
142 |
+
}).change();
|
143 |
+
jQuery('#advancedsettings').change(function(){
|
144 |
+
if ( jQuery('#advancedsettings').is(':checked') ) {
|
145 |
+
jQuery('#advancedgasettings').css("display","block");
|
146 |
+
jQuery('#customvarsettings').css("display","block");
|
147 |
+
jQuery('.advancedgasettings').css("display","list-item");
|
148 |
+
jQuery('.customvarsettings').css("display","list-item");
|
149 |
+
} else {
|
150 |
+
jQuery('#advancedgasettings').css("display","none");
|
151 |
+
jQuery('#customvarsettings').css("display","none");
|
152 |
+
jQuery('.advancedgasettings').css("display","none");
|
153 |
+
jQuery('.customvarsettings').css("display","none");
|
154 |
+
}
|
155 |
+
}).change();
|
156 |
+
jQuery('#extrase').change(function(){
|
157 |
+
if ( jQuery('#extrase').is(':checked') ) {
|
158 |
+
jQuery('#extrasebox').css("display","block");
|
159 |
+
} else {
|
160 |
+
jQuery('#extrasebox').css("display","none");
|
161 |
+
}
|
162 |
+
}).change();
|
163 |
+
jQuery('#gajslocalhosting').change(function(){
|
164 |
+
if ( jQuery('#gajslocalhosting').is(':checked') ) {
|
165 |
+
jQuery('#localhostingbox').css("display","block");
|
166 |
+
} else {
|
167 |
+
jQuery('#localhostingbox').css("display","none");
|
168 |
+
}
|
169 |
+
}).change();
|
170 |
+
jQuery('#customvarsettings :input').change(function() {
|
171 |
+
if (jQuery("#customvarsettings :input:checked").size() > 5) {
|
172 |
+
alert("<?php _e('The maximum number of allowed custom variables in Google Analytics is 5, please unselect one of the other custom variables before selecting this one.'); ?>");
|
173 |
+
jQuery(this).attr('checked', false);
|
174 |
+
};
|
175 |
+
});
|
176 |
+
jQuery('#uastring').change(function(){
|
177 |
+
if ( jQuery('#switchtomanual').is(':checked') ) {
|
178 |
+
if (!jQuery(this).val().match(/^UA-[\d-]+$/)) {
|
179 |
+
alert("<?php _e('That\'s not a valid UA ID, please make sure it matches the expected pattern of: UA-XXXXXX-X, and that there are no spaces or other characters in the input field.'); ?>");
|
180 |
+
jQuery(this).focus();
|
181 |
+
}
|
182 |
+
}
|
183 |
+
});
|
184 |
+
});
|
185 |
+
</script>
|
186 |
+
<link rel="shortcut icon" href="<?php echo $this->plugin_url; ?>images/favicon.ico" />
|
187 |
+
<?php
|
188 |
+
}
|
189 |
+
}
|
190 |
+
|
191 |
+
function plugin_help($contextual_help, $screen_id, $screen) {
|
192 |
+
if ( $screen_id == 'settings_page_'.$this->hook ) {
|
193 |
+
|
194 |
+
$contextual_help = '<h2>'.__('Having problems?').'</h2>'.
|
195 |
+
'<p>'.sprintf( __("If you're having problems with this plugin, please refer to its <a href='%s'>FAQ page</a>."), 'http://yoast.com/wordpress/google-analytics/ga-wp-faq/' ).'</p>';
|
196 |
+
}
|
197 |
+
return $contextual_help;
|
198 |
+
}
|
199 |
+
|
200 |
+
function toc( $modules ) {
|
201 |
+
$output = '<ul>';
|
202 |
+
foreach ($modules as $module => $key) {
|
203 |
+
$output .= '<li class="'.$key.'"><a href="#'.$key.'">'.$module.'</a></li>';
|
204 |
+
}
|
205 |
+
$output .= '</ul>';
|
206 |
+
return $output;
|
207 |
+
}
|
208 |
+
|
209 |
+
function save_settings() {
|
210 |
+
$options = get_option( $this->optionname );
|
211 |
+
|
212 |
+
if ( isset($_REQUEST['reset']) && $_REQUEST['reset'] == "true" && isset($_REQUEST['plugin']) && $_REQUEST['plugin'] == 'google-analytics-for-wordpress') {
|
213 |
+
$options = $this->set_defaults();
|
214 |
+
$options['msg'] = "<div class=\"updated\"><p>".__('Google Analytics settings reset.')."</p></div>\n";
|
215 |
+
} elseif ( isset($_POST['submit']) && isset($_POST['plugin']) && $_POST['plugin'] == 'google-analytics-for-wordpress') {
|
216 |
+
if (!current_user_can('manage_options')) die(__('You cannot edit the Google Analytics for WordPress options.'));
|
217 |
+
check_admin_referer('analyticspp-config');
|
218 |
+
|
219 |
+
foreach (array('uastring', 'dlextensions', 'domainorurl','position','domain', 'customcode', 'ga_token', 'extraseurl', 'gajsurl', 'gfsubmiteventpv', 'trackprefix', 'ignore_userlevel', 'internallink', 'internallinklabel', 'primarycrossdomain', 'othercrossdomains') as $option_name) {
|
220 |
+
if (isset($_POST[$option_name]))
|
221 |
+
$options[$option_name] = $_POST[$option_name];
|
222 |
+
else
|
223 |
+
$options[$option_name] = '';
|
224 |
+
}
|
225 |
+
|
226 |
+
foreach (array('extrase', 'trackoutbound', 'admintracking', 'trackadsense', 'allowanchor', 'allowlinker', 'allowhash', 'rsslinktagging', 'advancedsettings', 'trackregistration', 'theme_updated', 'cv_loggedin', 'cv_authorname', 'cv_category', 'cv_all_categories', 'cv_tags', 'cv_year', 'cv_post_type', 'outboundpageview', 'downloadspageview', 'trackcrossdomain','gajslocalhosting', 'manual_uastring', 'taggfsubmit', 'wpec_tracking', 'shopp_tracking', 'anonymizeip', 'trackcommentform', 'debug','firebuglite', 'disable_pagespeed_tracking') as $option_name) {
|
227 |
+
if (isset($_POST[$option_name]) && $_POST[$option_name] != 'off')
|
228 |
+
$options[$option_name] = true;
|
229 |
+
else
|
230 |
+
$options[$option_name] = false;
|
231 |
+
}
|
232 |
+
|
233 |
+
if (isset($_POST['manual_uastring']) && isset($_POST['uastring_man'])) {
|
234 |
+
$options['uastring'] = $_POST['uastring_man'];
|
235 |
+
}
|
236 |
+
|
237 |
+
if ( $options['trackcrossdomain'] ) {
|
238 |
+
if ( !$options['allowlinker'] )
|
239 |
+
$options['allowlinker'] = true;
|
240 |
+
|
241 |
+
if ( empty($options['primarycrossdomain']) ) {
|
242 |
+
$origin = GA_Filter::ga_get_domain($_SERVER["HTTP_HOST"]);
|
243 |
+
$options['primarycrossdomain'] = $origin["domain"];
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
$cache = '';
|
248 |
+
if ( function_exists('w3tc_pgcache_flush') ) {
|
249 |
+
w3tc_pgcache_flush();
|
250 |
+
w3tc_dbcache_flush();
|
251 |
+
w3tc_minify_flush();
|
252 |
+
w3tc_objectcache_flush();
|
253 |
+
$cache = ' and <strong>W3TC Caches cleared</strong>';
|
254 |
+
} else if ( function_exists('wp_cache_clear_cache') ) {
|
255 |
+
wp_cache_clear_cache();
|
256 |
+
$cache = ' and <strong>WP Super Cache cleared</strong>';
|
257 |
+
}
|
258 |
+
|
259 |
+
$options['msg'] = "<div id=\"updatemessage\" class=\"updated fade\"><p>Google Analytics <strong>settings updated</strong>$cache.</p></div>\n";
|
260 |
+
$options['msg'] .= "<script type=\"text/javascript\">setTimeout(function(){jQuery('#updatemessage').hide('slow');}, 3000);</script>";
|
261 |
+
}
|
262 |
+
update_option($this->optionname, $options);
|
263 |
+
}
|
264 |
+
|
265 |
+
function save_button() {
|
266 |
+
return '<div class="alignright"><input type="submit" class="button-primary" name="submit" value="'.__('Update Google Analytics Settings »').'" /></div><br class="clear"/>';
|
267 |
+
}
|
268 |
+
|
269 |
+
function upgrade() {
|
270 |
+
$options = get_option($this->optionname);
|
271 |
+
if ( isset($options['version']) && $options['version'] < '4.04' ) {
|
272 |
+
if ( !isset($options['ignore_userlevel']) || $options['ignore_userlevel'] == '')
|
273 |
+
$options['ignore_userlevel'] = 11;
|
274 |
+
}
|
275 |
+
if ( !isset($options['version']) || $options['version'] != GAWP_VERSION ) {
|
276 |
+
$options['version'] = GAWP_VERSION;
|
277 |
+
}
|
278 |
+
update_option($this->optionname, $options);
|
279 |
+
}
|
280 |
+
|
281 |
+
function config_page() {
|
282 |
+
$options = get_option($this->optionname);
|
283 |
+
if ( isset($options['msg']) )
|
284 |
+
echo $options['msg'];
|
285 |
+
$options['msg'] = '';
|
286 |
+
update_option($this->optionname, $options);
|
287 |
+
|
288 |
+
if ( !isset($options['uastring']) )
|
289 |
+
$options = $this->set_defaults();
|
290 |
+
$modules = array();
|
291 |
+
|
292 |
+
?>
|
293 |
+
<div class="wrap">
|
294 |
+
<a href="http://yoast.com/"><div id="yoast-icon" style="background: url(<?php echo $this->plugin_url; ?>images/ga-icon-32x32.png) no-repeat;" class="icon32"><br /></div></a>
|
295 |
+
<h2><?php _e("Google Analytics for WordPress Configuration") ?></h2>
|
296 |
+
<div class="postbox-container" style="width:65%;">
|
297 |
+
<div class="metabox-holder">
|
298 |
+
<div class="meta-box-sortables">
|
299 |
+
<form action="<?php echo $this->plugin_options_url(); ?>" method="post" id="analytics-conf">
|
300 |
+
<input type="hidden" name="plugin" value="google-analytics-for-wordpress"/>
|
301 |
+
<?php
|
302 |
+
wp_nonce_field('analyticspp-config');
|
303 |
+
|
304 |
+
if ( empty($options['uastring']) && empty($options['ga_token']) ) {
|
305 |
+
$query = $this->plugin_options_url().'&reauth=true';
|
306 |
+
$line = 'Please authenticate with Google Analytics to retrieve your tracking code:<br/><br/> <a class="button-primary" href="'.$query.'">Click here to authenticate with Google</a><br/><br/><strong>Note</strong>: if you have multiple Google accounts, you\'ll want to switch to the right account first, since Google doesn\'t let you switch accounts on the authentication screen.';
|
307 |
+
} else if(isset($options['ga_token']) && !empty($options['ga_token'])) {
|
308 |
+
$token = $options['ga_token'];
|
309 |
+
|
310 |
+
require_once plugin_dir_path(__FILE__).'xmlparser.php';
|
311 |
+
if (file_exists(ABSPATH.'wp-includes/class-http.php'))
|
312 |
+
require_once(ABSPATH.'wp-includes/class-http.php');
|
313 |
+
|
314 |
+
if (!isset($options['ga_api_responses'][$token])) {
|
315 |
+
$options['ga_api_responses'] = array();
|
316 |
+
|
317 |
+
if ( $oauth = $options['gawp_oauth'] ) {
|
318 |
+
if ( isset( $oauth['params']['oauth_token'], $oauth['params']['oauth_token_secret'] ) ) {
|
319 |
+
$options['gawp_oauth']['access_token'] = array(
|
320 |
+
'oauth_token' => base64_decode( $oauth['params']['oauth_token'] ),
|
321 |
+
'oauth_token_secret' => base64_decode( $oauth['params']['oauth_token_secret'] )
|
322 |
+
);
|
323 |
+
unset( $options['gawp_oauth']['params'] );
|
324 |
+
update_option( $this->optionname, $options );
|
325 |
+
}
|
326 |
+
}
|
327 |
+
|
328 |
+
$args = array(
|
329 |
+
'scope' => 'https://www.google.com/analytics/feeds/',
|
330 |
+
'xoauth_displayname' => 'Google Analytics for WordPress by Yoast'
|
331 |
+
);
|
332 |
+
$access_token = $options['gawp_oauth']['access_token'];
|
333 |
+
$gdata = new WP_Gdata( $args, $access_token['oauth_token'], $access_token['oauth_token_secret'] );
|
334 |
+
|
335 |
+
|
336 |
+
$response = $gdata->get( 'https://www.google.com/analytics/feeds/accounts/default' );
|
337 |
+
$http_code = wp_remote_retrieve_response_code( $response );
|
338 |
+
$response = wp_remote_retrieve_body( $response );
|
339 |
+
|
340 |
+
|
341 |
+
if($http_code==200)
|
342 |
+
{
|
343 |
+
$options['ga_api_responses'][$token] = array(
|
344 |
+
'response'=>array('code'=>$http_code),
|
345 |
+
'body'=>$response
|
346 |
+
);
|
347 |
+
$options['ga_token'] = $token;
|
348 |
+
update_option('Yoast_Google_Analytics', $options);
|
349 |
+
}
|
350 |
+
}
|
351 |
+
|
352 |
+
if (is_array($options['ga_api_responses'][$token]) && $options['ga_api_responses'][$token]['response']['code'] == 200) {
|
353 |
+
$arr = yoast_xml2array($options['ga_api_responses'][$token]['body']);
|
354 |
+
|
355 |
+
$ga_accounts = array();
|
356 |
+
if (isset($arr['feed']['entry'][0])) {
|
357 |
+
foreach ($arr['feed']['entry'] as $site) {
|
358 |
+
$ua = $site['dxp:property']['3_attr']['value'];
|
359 |
+
$account = $site['dxp:property']['1_attr']['value'];
|
360 |
+
if (!isset($ga_accounts[$account]) || !is_array($ga_accounts[$account]))
|
361 |
+
$ga_accounts[$account] = array();
|
362 |
+
$ga_accounts[$account][$site['title']] = $ua;
|
363 |
+
}
|
364 |
+
} else {
|
365 |
+
$ua = $arr['feed']['entry']['dxp:property']['3_attr']['value'];
|
366 |
+
$account = $arr['feed']['entry']['dxp:property']['1_attr']['value'];
|
367 |
+
$title = $arr['feed']['entry']['title'];
|
368 |
+
if (!isset($ga_accounts[$account]) || !is_array($ga_accounts[$account]))
|
369 |
+
$ga_accounts[$account] = array();
|
370 |
+
$ga_accounts[$account][$title] = $ua;
|
371 |
+
}
|
372 |
+
|
373 |
+
$select1 = '<select style="width:150px;" name="ga_account" id="ga_account">';
|
374 |
+
$select1 .= "\t<option></option>\n";
|
375 |
+
$select2 = '<select style="width:150px;" name="uastring" id="uastring_sel">';
|
376 |
+
$i = 1;
|
377 |
+
$currentua = '';
|
378 |
+
if (!empty($options['uastring']))
|
379 |
+
$currentua = $options['uastring'];
|
380 |
+
|
381 |
+
foreach($ga_accounts as $account => $val) {
|
382 |
+
$accountsel = false;
|
383 |
+
foreach ($val as $title => $ua) {
|
384 |
+
$sel = selected($ua, $currentua, false);
|
385 |
+
if (!empty($sel)) {
|
386 |
+
$accountsel = true;
|
387 |
+
}
|
388 |
+
$select2 .= "\t".'<option class="sub_'.$i.'" '.$sel.' value="'.$ua.'">'.$title.' - '.$ua.'</option>'."\n";
|
389 |
+
}
|
390 |
+
$select1 .= "\t".'<option '.selected($accountsel,true,false).' value="'.$i.'">'.$account.'</option>'."\n";
|
391 |
+
$i++;
|
392 |
+
}
|
393 |
+
$select1 .= '</select>';
|
394 |
+
$select2 .= '</select>';
|
395 |
+
|
396 |
+
$line = '<input type="hidden" name="ga_token" value="'.$token.'"/>';
|
397 |
+
$line .= 'Please select the correct Analytics profile to track:<br/>';
|
398 |
+
$line .= '<table class="form_table">';
|
399 |
+
$line .= '<tr><th width="15%">Account:</th><td width="85%">'.$select1.'</td></tr>';
|
400 |
+
$line .= '<tr><th>Profile:</th><td>'.$select2.'</td></tr>';
|
401 |
+
$line .= '</table>';
|
402 |
+
|
403 |
+
$try = 1;
|
404 |
+
if (isset($_GET['try']))
|
405 |
+
$try = $_GET['try'] + 1;
|
406 |
+
|
407 |
+
if ($i == 1 && $try < 4 && isset($_GET['token'])) {
|
408 |
+
$line .= '<script type="text/javascript">
|
409 |
+
window.location="'.$this->plugin_options_url().'&switchua=1&token='.$token.'&try='.$try.'";
|
410 |
+
</script>';
|
411 |
+
}
|
412 |
+
$line .= 'Please note that if you have several profiles of the same website, it doesn\'t matter which profile you select, and in fact another profile might show as selected later. You can check whether they\'re profiles for the same site by checking if they have the same UA code. If that\'s true, tracking will be correct.<br/>';
|
413 |
+
$line .= '<br/>Refresh this listing or switch to another account: ';
|
414 |
+
} else {
|
415 |
+
$line = 'Unfortunately, an error occurred while connecting to Google, please try again:';
|
416 |
+
}
|
417 |
+
|
418 |
+
$query = $this->plugin_options_url().'&reauth=true';
|
419 |
+
$line .= '<a class="button" href="'.$query.'">Re-authenticate with Google</a>';
|
420 |
+
} else {
|
421 |
+
$line = '<input id="uastring" name="uastring" type="text" size="20" maxlength="40" value="'.$options['uastring'].'"/><br/><a href="'.$this->plugin_options_url().'&switchua=1">Select another Analytics Profile »</a>';
|
422 |
+
}
|
423 |
+
$line = '<div id="uastring_automatic">'.$line.'</div><div style="display:none;" id="uastring_manual">Manually enter your UA code: <input id="uastring" name="uastring_man" type="text" size="20" maxlength="40" value="'.$options['uastring'].'"/></div>';
|
424 |
+
$rows = array();
|
425 |
+
$content = '';
|
426 |
+
$rows[] = array(
|
427 |
+
'id' => 'uastring',
|
428 |
+
'label' => 'Analytics Profile',
|
429 |
+
'desc' => '<input type="checkbox" name="manual_uastring" '.checked($options['manual_uastring'], true, false).' id="switchtomanual"/> <label for="switchtomanual">Manually enter your UA code</label>',
|
430 |
+
'content' => $line
|
431 |
+
);
|
432 |
+
$temp_content = $this->select('position', array('header' => 'In the header (default)', 'manual' => 'Insert manually'));
|
433 |
+
if ($options['theme_updated'] && $options['position'] == 'manual') {
|
434 |
+
$temp_content .= '<input type="hidden" name="theme_updated" value="off"/>';
|
435 |
+
echo '<div id="message" class="updated" style="background-color:lightgreen;border-color:green;"><p><strong>Notice:</strong> You switched your theme, please make sure your Google Analytics tracking is still ok. Save your settings to make sure Google Analytics gets loaded properly.</p></div>';
|
436 |
+
remove_action('admin_footer', array(&$this,'theme_switch_warning'));
|
437 |
+
}
|
438 |
+
$desc = '<div id="position_header">The header is by far the best spot to place the tracking code. If you\'d rather place the code manually, switch to manual placement. For more info <a href="http://yoast.com/wordpress/google-analytics/manual-placement/">read this page</a>.</div>';
|
439 |
+
$desc .= '<div id="position_manual"><a href="http://yoast.com/wordpress/google-analytics/manual-placement/">Follow the instructions here</a> to choose the location for your tracking code manually.</div>';
|
440 |
+
|
441 |
+
$rows[] = array(
|
442 |
+
'id' => 'position',
|
443 |
+
'label' => 'Where should the tracking code be placed',
|
444 |
+
'desc' => $desc,
|
445 |
+
'content' => $temp_content,
|
446 |
+
);
|
447 |
+
$rows[] = array(
|
448 |
+
'id' => 'trackoutbound',
|
449 |
+
'label' => 'Track outbound clicks & downloads',
|
450 |
+
'desc' => 'Clicks & downloads will be tracked as events, you can find these under Content » Event Tracking in your Google Analytics reports.',
|
451 |
+
'content' => $this->checkbox('trackoutbound'),
|
452 |
+
);
|
453 |
+
$rows[] = array(
|
454 |
+
'id' => 'advancedsettings',
|
455 |
+
'label' => 'Show advanced settings',
|
456 |
+
'desc' => 'Only adviced for advanced users who know their way around Google Analytics',
|
457 |
+
'content' => $this->checkbox('advancedsettings'),
|
458 |
+
);
|
459 |
+
$this->postbox('gasettings','Google Analytics Settings',$this->form_table($rows).$this->save_button());
|
460 |
+
|
461 |
+
$rows = array();
|
462 |
+
$pre_content = '<p>Google Analytics allows you to save up to 5 custom variables on each page, and this plugin helps you make the most use of these! Check which custom variables you\'d like the plugin to save for you below. Please note that these will only be saved when they are actually available.</p><p>If you want to start using these custom variables, go to Visitors » Custom Variables in your Analytics reports.</p>';
|
463 |
+
$rows[] = array(
|
464 |
+
'id' => 'cv_loggedin',
|
465 |
+
'label' => 'Logged in Users',
|
466 |
+
'desc' => 'Allows you to easily remove logged in users from your reports, or to segment by different user roles. The users primary role will be logged.',
|
467 |
+
'content' => $this->checkbox('cv_loggedin'),
|
468 |
+
);
|
469 |
+
$rows[] = array(
|
470 |
+
'id' => 'cv_post_type',
|
471 |
+
'label' => 'Post type',
|
472 |
+
'desc' => 'Allows you to see pageviews per post type, especially useful if you use multiple custom post types.',
|
473 |
+
'content' => $this->checkbox('cv_post_type'),
|
474 |
+
);
|
475 |
+
$rows[] = array(
|
476 |
+
'id' => 'cv_authorname',
|
477 |
+
'label' => 'Author Name',
|
478 |
+
'desc' => 'Allows you to see pageviews per author.',
|
479 |
+
'content' => $this->checkbox('cv_authorname'),
|
480 |
+
);
|
481 |
+
$rows[] = array(
|
482 |
+
'id' => 'cv_tags',
|
483 |
+
'label' => 'Tags',
|
484 |
+
'desc' => 'Allows you to see pageviews per tags using advanced segments.',
|
485 |
+
'content' => $this->checkbox('cv_tags'),
|
486 |
+
);
|
487 |
+
$rows[] = array(
|
488 |
+
'id' => 'cv_year',
|
489 |
+
'label' => 'Publication year',
|
490 |
+
'desc' => 'Allows you to see pageviews per year of publication, showing you if your old posts still get traffic.',
|
491 |
+
'content' => $this->checkbox('cv_year'),
|
492 |
+
);
|
493 |
+
$rows[] = array(
|
494 |
+
'id' => 'cv_category',
|
495 |
+
'label' => 'Single Category',
|
496 |
+
'desc' => 'Allows you to see pageviews per category, works best when each post is in only one category.',
|
497 |
+
'content' => $this->checkbox('cv_category'),
|
498 |
+
);
|
499 |
+
$rows[] = array(
|
500 |
+
'id' => 'cv_all_categories',
|
501 |
+
'label' => 'All Categories',
|
502 |
+
'desc' => 'Allows you to see pageviews per category using advanced segments, should be used when you use multiple categories per post.',
|
503 |
+
'content' => $this->checkbox('cv_all_categories'),
|
504 |
+
);
|
505 |
+
|
506 |
+
$modules['Custom Variables'] = 'customvarsettings';
|
507 |
+
$this->postbox('customvarsettings','Custom Variables Settings',$pre_content.$this->form_table($rows).$this->save_button());
|
508 |
+
|
509 |
+
$rows = array();
|
510 |
+
$rows[] = array(
|
511 |
+
'id' => 'ignore_userlevel',
|
512 |
+
'label' => 'Ignore users',
|
513 |
+
'desc' => 'Users of the role you select and higher will be ignored, so if you select Editor, all Editors and Administrators will be ignored.',
|
514 |
+
'content' => $this->select('ignore_userlevel', array(
|
515 |
+
'11' => 'Ignore no-one',
|
516 |
+
'8' => 'Administrator',
|
517 |
+
'5' => 'Editor',
|
518 |
+
'2' => 'Author',
|
519 |
+
'1' => 'Contributor',
|
520 |
+
'0' => 'Subscriber (ignores all logged in users)',
|
521 |
+
)),
|
522 |
+
);
|
523 |
+
$rows[] = array(
|
524 |
+
'id' => 'outboundpageview',
|
525 |
+
'label' => 'Track outbound clicks as pageviews',
|
526 |
+
'desc' => 'You do not need to enable this to enable outbound click tracking, this changes the default behavior of tracking clicks as events to tracking them as pageviews. This is therefore not recommended, as this would skew your statistics, but <em>is</em> sometimes necessary when you need to set outbound clicks as goals.',
|
527 |
+
'content' => $this->checkbox('outboundpageview'),
|
528 |
+
);
|
529 |
+
$rows[] = array(
|
530 |
+
'id' => 'downloadspageview',
|
531 |
+
'label' => 'Track downloads as pageviews',
|
532 |
+
'desc' => 'Not recommended, as this would skew your statistics, but it does make it possible to track downloads as goals.',
|
533 |
+
'content' => $this->checkbox('downloadspageview'),
|
534 |
+
);
|
535 |
+
$rows[] = array(
|
536 |
+
'id' => 'dlextensions',
|
537 |
+
'label' => 'Extensions of files to track as downloads',
|
538 |
+
'content' => $this->textinput('dlextensions'),
|
539 |
+
);
|
540 |
+
if ( $options['outboundpageview'] ) {
|
541 |
+
$rows[] = array(
|
542 |
+
'id' => 'trackprefix',
|
543 |
+
'label' => 'Prefix to use in Analytics before the tracked pageviews',
|
544 |
+
'desc' => 'This prefix is used before all pageviews, they are then segmented automatically after that. If nothing is entered here, <code>/yoast-ga/</code> is used.',
|
545 |
+
'content' => $this->textinput('trackprefix'),
|
546 |
+
);
|
547 |
+
}
|
548 |
+
$rows[] = array(
|
549 |
+
'id' => 'domainorurl',
|
550 |
+
'label' => 'Track full URL of outbound clicks or just the domain',
|
551 |
+
'content' => $this->select('domainorurl', array(
|
552 |
+
'domain' => 'Just the domain',
|
553 |
+
'url' => 'Track the complete URL',
|
554 |
+
)
|
555 |
+
),
|
556 |
+
);
|
557 |
+
$rows[] = array(
|
558 |
+
'id' => 'domain',
|
559 |
+
'label' => 'Subdomain Tracking',
|
560 |
+
'desc' => 'This allows you to set the domain that\'s set by <a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName"><code>setDomainName</code></a> for tracking subdomains, if empty this will not be set.',
|
561 |
+
'content' => $this->textinput('domain'),
|
562 |
+
);
|
563 |
+
$rows[] = array(
|
564 |
+
'id' => 'trackcrossdomain',
|
565 |
+
'label' => 'Enable Cross Domain Tracking',
|
566 |
+
'desc' => 'This allows you to enable <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html">Cross-Domain Tracking</a> for this site. When endabled <code>_setAllowLinker:</code> will be enabled if it is not already.',
|
567 |
+
'content' => $this->checkbox('trackcrossdomain'),
|
568 |
+
);
|
569 |
+
$rows[] = array(
|
570 |
+
'id' => 'primarycrossdomain',
|
571 |
+
'label' => 'Cross-Domain Tracking, Primary Domain',
|
572 |
+
'desc' => 'Set the primary domain used in <a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setDomainName"><code>setDomainName</code></a> for cross domain tracking (eg. <code>example-petstore.com</code> ), if empty this will default to your configured Home URL.',
|
573 |
+
'content' => $this->textinput('primarycrossdomain'),
|
574 |
+
);
|
575 |
+
$rows[] = array(
|
576 |
+
'id' => 'othercrossdomains',
|
577 |
+
'label' => 'Cross-Domain Tracking, Other Domains',
|
578 |
+
'desc' => 'All links to these domains will have the <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingSite.html#multipleDomains"><code>_link</code></a> code automatically attached. Separate domains/sub-domains with commas (eg. <code>dogs.example-petstore.com, cats.example-petstore.com</code>)',
|
579 |
+
'content' => $this->textinput('othercrossdomains'),
|
580 |
+
);
|
581 |
+
$rows[] = array(
|
582 |
+
'id' => 'disable_pagespeed_tracking',
|
583 |
+
'label' => 'Disable Site Speed tracking',
|
584 |
+
'desc' => 'This disables the Site Speed tracking feature of Google Analytics that is enabled by default in this plugin.',
|
585 |
+
'content' => $this->checkbox('disable_pagespeed_tracking'),
|
586 |
+
);
|
587 |
+
$rows[] = array(
|
588 |
+
'id' => 'customcode',
|
589 |
+
'label' => 'Custom Code',
|
590 |
+
'desc' => 'Not for the average user: this allows you to add a line of code, to be added before the <code>trackPageview</code> call.',
|
591 |
+
'content' => $this->textinput('customcode'),
|
592 |
+
);
|
593 |
+
$rows[] = array(
|
594 |
+
'id' => 'trackadsense',
|
595 |
+
'label' => 'Track AdSense',
|
596 |
+
'desc' => 'This requires integration of your Analytics and AdSense account, for help, <a href="http://google.com/support/analytics/bin/answer.py?answer=92625">look here</a>.',
|
597 |
+
'content' => $this->checkbox('trackadsense'),
|
598 |
+
);
|
599 |
+
$rows[] = array(
|
600 |
+
'id' => 'gajslocalhosting',
|
601 |
+
'label' => 'Host ga.js locally',
|
602 |
+
'content' => $this->checkbox('gajslocalhosting').'<div id="localhostingbox">
|
603 |
+
You have to provide a URL to your ga.js file:
|
604 |
+
<input type="text" name="gajsurl" size="30" value="'.$options['gajsurl'].'"/>
|
605 |
+
</div>',
|
606 |
+
'desc' => 'For some reasons you might want to use a locally hosted ga.js file, or another ga.js file, check the box and then please enter the full URL including http here.'
|
607 |
+
);
|
608 |
+
$rows[] = array(
|
609 |
+
'id' => 'extrase',
|
610 |
+
'label' => 'Track extra Search Engines',
|
611 |
+
'content' => $this->checkbox('extrase').'<div id="extrasebox">
|
612 |
+
You can provide a custom URL to the extra search engines file if you want:
|
613 |
+
<input type="text" name="extraseurl" size="30" value="'.$options['extraseurl'].'"/>
|
614 |
+
</div>',
|
615 |
+
);
|
616 |
+
$rows[] = array(
|
617 |
+
'id' => 'rsslinktagging',
|
618 |
+
'label' => 'Tag links in RSS feed with campaign variables',
|
619 |
+
'desc' => 'Do not use this feature if you use FeedBurner, as FeedBurner can do this automatically, and better than this plugin can. Check <a href="http://www.google.com/support/feedburner/bin/answer.py?hl=en&answer=165769">this help page</a> for info on how to enable this feature in FeedBurner.',
|
620 |
+
'content' => $this->checkbox('rsslinktagging'),
|
621 |
+
);
|
622 |
+
$rows[] = array(
|
623 |
+
'id' => 'trackregistration',
|
624 |
+
'label' => 'Add tracking to the login and registration forms',
|
625 |
+
'content' => $this->checkbox('trackregistration'),
|
626 |
+
);
|
627 |
+
$rows[] = array(
|
628 |
+
'id' => 'trackcommentform',
|
629 |
+
'label' => 'Add tracking to the comment forms',
|
630 |
+
'content' => $this->checkbox('trackcommentform'),
|
631 |
+
);
|
632 |
+
$rows[] = array(
|
633 |
+
'id' => 'allowanchor',
|
634 |
+
'label' => 'Use # instead of ? for Campaign tracking',
|
635 |
+
'desc' => 'This adds a <code><a href="http://code.google.com/apis/analytics/docs/gaJSApiCampaignTracking.html#_gat.GA_Tracker_._setAllowAnchor">_setAllowAnchor</a></code> call to your tracking code, and makes RSS link tagging use a # as well.',
|
636 |
+
'content' => $this->checkbox('allowanchor'),
|
637 |
+
);
|
638 |
+
$rows[] = array(
|
639 |
+
'id' => 'allowlinker',
|
640 |
+
'label' => 'Add <code>_setAllowLinker</code>',
|
641 |
+
'desc' => 'This adds a <code><a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowLinker">_setAllowLinker</a></code> call to your tracking code, allowing you to use <code>_link</code> and related functions.',
|
642 |
+
'content' => $this->checkbox('allowlinker'),
|
643 |
+
);
|
644 |
+
$rows[] = array(
|
645 |
+
'id' => 'allowhash',
|
646 |
+
'label' => 'Set <code>_setAllowHash</code> to false',
|
647 |
+
'desc' => 'This sets <code><a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowHash">_setAllowHash</a></code> to false, allowing you to track subdomains etc.',
|
648 |
+
'content' => $this->checkbox('allowhash'),
|
649 |
+
);
|
650 |
+
$rows[] = array(
|
651 |
+
'id' => 'anonymizeip',
|
652 |
+
'label' => 'Anonymize IP\'s',
|
653 |
+
'desc' => 'This adds <code><a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gat.html#_gat._anonymizeIp">_anonymizeIp</a></code>, telling Google Analytics to anonymize the information sent by the tracker objects by removing the last octet of the IP address prior to its storage.',
|
654 |
+
'content' => $this->checkbox('anonymizeip'),
|
655 |
+
);
|
656 |
+
$modules['Advanced Settings'] = 'advancedgasettings';
|
657 |
+
$this->postbox('advancedgasettings','Advanced Settings',$this->form_table($rows).$this->save_button());
|
658 |
+
|
659 |
+
$rows = array();
|
660 |
+
$rows[] = array(
|
661 |
+
'id' => 'internallink',
|
662 |
+
'label' => 'Internal links to track as outbound',
|
663 |
+
'desc' => 'If you want to track all internal links that begin with <code>/out/</code>, enter <code>/out/</code> in the box above. If you have multiple prefixes you can separate them with comma\'s: <code>/out/,/recommends/</code>',
|
664 |
+
'content' => $this->textinput('internallink'),
|
665 |
+
);
|
666 |
+
$rows[] = array(
|
667 |
+
'id' => 'internallinklabel',
|
668 |
+
'label' => 'Label to use',
|
669 |
+
'desc' => 'The label to use for these links, this will be added to where the click came from, so if the label is "aff", the label for a click from the content of an article becomes "outbound-article-aff".',
|
670 |
+
'content' => $this->textinput('internallinklabel'),
|
671 |
+
);
|
672 |
+
$modules['Internal Link Tracking'] = 'internallinktracking';
|
673 |
+
$this->postbox('internallinktracking','Internal Links to Track as Outbound',$this->form_table($rows).$this->save_button());
|
674 |
+
|
675 |
+
/* if (class_exists('RGForms') && GFCommon::$version >= '1.3.11') {
|
676 |
+
$pre_content = 'This plugin can automatically tag your Gravity Forms to track form submissions as either events or pageviews';
|
677 |
+
$rows = array();
|
678 |
+
$rows[] = array(
|
679 |
+
'id' => 'taggfsubmit',
|
680 |
+
'label' => 'Tag Gravity Forms',
|
681 |
+
'content' => $this->checkbox('taggfsubmit'),
|
682 |
+
);
|
683 |
+
$rows[] = array(
|
684 |
+
'id' => 'gfsubmiteventpv',
|
685 |
+
'label' => 'Tag Gravity Forms as',
|
686 |
+
'content' => '<select name="gfsubmiteventpv">
|
687 |
+
<option value="events" '.selected($options['gfsubmiteventpv'],'events',false).'>Events</option>
|
688 |
+
<option value="pageviews" '.selected($options['gfsubmiteventpv'],'pageviews',false).'>Pageviews</option>
|
689 |
+
</select>',
|
690 |
+
);
|
691 |
+
$this->postbox('gravityforms','Gravity Forms Settings',$pre_content.$this->form_table($rows).$this->save_button());
|
692 |
+
$modules['Gravity Forms'] = 'gravityforms';
|
693 |
+
}
|
694 |
+
*/
|
695 |
+
if ( defined('WPSC_VERSION') ) {
|
696 |
+
$pre_content = 'The WordPress e-Commerce plugin has been detected. This plugin can automatically add transaction tracking for you. To do that, <a href="http://yoast.com/wordpress/google-analytics/enable-ecommerce/">enable e-commerce for your reports in Google Analytics</a> and then check the box below.';
|
697 |
+
$rows = array();
|
698 |
+
$rows[] = array(
|
699 |
+
'id' => 'wpec_tracking',
|
700 |
+
'label' => 'Enable transaction tracking',
|
701 |
+
'content' => $this->checkbox('wpec_tracking'),
|
702 |
+
);
|
703 |
+
$this->postbox('wpecommerce','WordPress e-Commerce Settings',$pre_content.$this->form_table($rows).$this->save_button());
|
704 |
+
$modules['WordPress e-Commerce'] = 'wpecommerce';
|
705 |
+
}
|
706 |
+
|
707 |
+
global $Shopp;
|
708 |
+
if ( isset($Shopp) ) {
|
709 |
+
$pre_content = 'The Shopp e-Commerce plugin has been detected. This plugin can automatically add transaction tracking for you. To do that, <a href="http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=55528">enable e-commerce for your reports in Google Analytics</a> and then check the box below.';
|
710 |
+
$rows = array();
|
711 |
+
$rows[] = array(
|
712 |
+
'id' => 'shopp_tracking',
|
713 |
+
'label' => 'Enable transaction tracking',
|
714 |
+
'content' => $this->checkbox('shopp_tracking'),
|
715 |
+
);
|
716 |
+
$this->postbox('shoppecommerce','Shopp e-Commerce Settings',$pre_content.$this->form_table($rows).$this->save_button());
|
717 |
+
$modules['Shopp'] = 'shoppecommerce';
|
718 |
+
}
|
719 |
+
$pre_content = '<p>If you want to confirm that tracking on your blog is working as it should, enable this option and check the console in <a href="http://getfirebug.com/">Firebug</a> (for Firefox), <a href="http://getfirebug.com/firebuglite">Firebug Lite</a> (for other browsers) or Chrome & Safari\'s Web Inspector. Be absolutely sure to disable debugging afterwards, as it is slower than normal tracking.</p><p><strong>Note</strong>: the debugging and firebug scripts are only loaded for admins.</p>';
|
720 |
+
$rows = array();
|
721 |
+
$rows[] = array(
|
722 |
+
'id' => 'debug',
|
723 |
+
'label' => 'Enable debug mode',
|
724 |
+
'content' => $this->checkbox('debug'),
|
725 |
+
);
|
726 |
+
$rows[] = array(
|
727 |
+
'id' => 'firebuglite',
|
728 |
+
'label' => 'Enable Firebug Lite',
|
729 |
+
'content' => $this->checkbox('firebuglite'),
|
730 |
+
);
|
731 |
+
$this->postbox('debugmode','Debug Mode',$pre_content.$this->form_table($rows).$this->save_button());
|
732 |
+
$modules['Debug Mode'] = 'debugmode';
|
733 |
+
?>
|
734 |
+
</form>
|
735 |
+
<form action="<?php echo $this->plugin_options_url(); ?>" method="post" onsubmit="javascript:return(confirm('Do you really want to reset all settings?'));">
|
736 |
+
<input type="hidden" name="reset" value="true"/>
|
737 |
+
<input type="hidden" name="plugin" value="google-analytics-for-wordpress"/>
|
738 |
+
<div class="submit"><input type="submit" value="Reset All Settings »" /></div>
|
739 |
+
</form>
|
740 |
+
</div>
|
741 |
+
</div>
|
742 |
+
</div>
|
743 |
+
<div class="postbox-container side" style="width:20%;">
|
744 |
+
<div class="metabox-holder">
|
745 |
+
<div class="meta-box-sortables">
|
746 |
+
<?php
|
747 |
+
if ( count($modules) > 0 )
|
748 |
+
$this->postbox('toc','List of Available Modules',$this->toc($modules));
|
749 |
+
$this->plugin_like();
|
750 |
+
$this->postbox('donate','<strong class="red">Donate $10, $20 or $50!</strong>','<p>This plugin has cost me countless hours of work, if you use it, please donate a token of your appreciation!</p><br/><form style="margin-left:50px;" action="https://www.paypal.com/cgi-bin/webscr" method="post">
|
751 |
+
<input type="hidden" name="cmd" value="_s-xclick">
|
752 |
+
<input type="hidden" name="hosted_button_id" value="FW9FK4EBZ9FVJ">
|
753 |
+
<input type="image" src="https://www.paypal.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
|
754 |
+
<img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
|
755 |
+
</form>');
|
756 |
+
$this->plugin_support();
|
757 |
+
$this->news();
|
758 |
+
?>
|
759 |
+
</div>
|
760 |
+
<br/><br/><br/>
|
761 |
+
</div>
|
762 |
+
</div>
|
763 |
+
</div>
|
764 |
+
<?php
|
765 |
+
}
|
766 |
+
|
767 |
+
function set_defaults() {
|
768 |
+
$options = array(
|
769 |
+
'advancedsettings' => false,
|
770 |
+
'allowanchor' => false,
|
771 |
+
'allowhash' => false,
|
772 |
+
'allowlinker' => false,
|
773 |
+
'anonymizeip' => false,
|
774 |
+
'customcode' => '',
|
775 |
+
'cv_loggedin' => false,
|
776 |
+
'cv_authorname' => false,
|
777 |
+
'cv_category' => false,
|
778 |
+
'cv_all_categories' => false,
|
779 |
+
'cv_tags' => false,
|
780 |
+
'cv_year' => false,
|
781 |
+
'cv_post_type' => false,
|
782 |
+
'debug' => false,
|
783 |
+
'dlextensions' => 'doc,exe,js,pdf,ppt,tgz,zip,xls',
|
784 |
+
'domain' => '',
|
785 |
+
'domainorurl' => 'domain',
|
786 |
+
'extrase' => false,
|
787 |
+
'extraseurl' => '',
|
788 |
+
'firebuglite' => false,
|
789 |
+
'ga_token' => '',
|
790 |
+
'ga_api_responses' => array(),
|
791 |
+
'gajslocalhosting' => false,
|
792 |
+
'gajsurl' => '',
|
793 |
+
'ignore_userlevel' => '11',
|
794 |
+
'internallink' => false,
|
795 |
+
'internallinklabel' => '',
|
796 |
+
'outboundpageview' => false,
|
797 |
+
'downloadspageview' => false,
|
798 |
+
'othercrossdomains' => '',
|
799 |
+
'position' => 'footer',
|
800 |
+
'primarycrossdomain' => '',
|
801 |
+
'theme_updated' => false,
|
802 |
+
'trackcommentform' => true,
|
803 |
+
'trackcrossdomain' => false,
|
804 |
+
'trackadsense' => false,
|
805 |
+
'trackoutbound' => true,
|
806 |
+
'trackregistration' => false,
|
807 |
+
'rsslinktagging' => true,
|
808 |
+
'uastring' => '',
|
809 |
+
'version' => GAWP_VERSION,
|
810 |
+
);
|
811 |
+
update_option($this->optionname,$options);
|
812 |
+
return $options;
|
813 |
+
}
|
814 |
+
|
815 |
+
function warning() {
|
816 |
+
$options = get_option($this->optionname);
|
817 |
+
if (!isset($options['uastring']) || empty($options['uastring'])) {
|
818 |
+
echo "<div id='message' class='error'><p><strong>Google Analytics is not active.</strong> You must <a href='".$this->plugin_options_url()."'>select which Analytics Profile to track</a> before it can work.</p></div>";
|
819 |
+
}
|
820 |
+
} // end warning()
|
821 |
+
|
822 |
+
|
823 |
+
function authenticate() {
|
824 |
+
if ( isset( $_REQUEST['oauth_token'] ) ) {
|
825 |
+
$o = get_option( $this->optionname );
|
826 |
+
if ( isset( $o['gawp_oauth']['oauth_token'] ) && $o['gawp_oauth']['oauth_token'] !== $_REQUEST['oauth_token'] ) {
|
827 |
+
$o['gawp_oauth']['oauth_token'] = '';
|
828 |
+
} else {
|
829 |
+
$gdata = new WP_GData(
|
830 |
+
array(
|
831 |
+
'scope' => 'https://www.google.com/analytics/feeds/',
|
832 |
+
'xoauth_displayname' => 'Google Analytics for WordPress by Yoast'
|
833 |
+
),
|
834 |
+
$o['gawp_oauth']['oauth_token'],
|
835 |
+
$o['gawp_oauth']['oauth_token_secret']
|
836 |
+
);
|
837 |
+
|
838 |
+
$o['gawp_oauth']['access_token'] = $gdata->get_access_token( $_REQUEST['oauth_verifier'] );
|
839 |
+
unset( $o['gawp_oauth']['oauth_token'] );
|
840 |
+
unset( $o['gawp_oauth']['oauth_token_secret'] );
|
841 |
+
$o['ga_token'] = $o['gawp_oauth']['access_token']['oauth_token'];
|
842 |
+
}
|
843 |
+
|
844 |
+
update_option( $this->optionname, $o );
|
845 |
+
|
846 |
+
wp_redirect( menu_page_url( $this->hook, false ) );
|
847 |
+
exit;
|
848 |
+
}
|
849 |
+
|
850 |
+
if ( ! empty( $_GET['reauth'] ) ) {
|
851 |
+
$gdata = new WP_GData(
|
852 |
+
array(
|
853 |
+
'scope' => 'https://www.google.com/analytics/feeds/',
|
854 |
+
'xoauth_displayname' => 'Google Analytics for WordPress by Yoast'
|
855 |
+
)
|
856 |
+
);
|
857 |
+
|
858 |
+
$request_token = $gdata->get_request_token( menu_page_url( 'google-analytics-for-wordpress', false ) );
|
859 |
+
|
860 |
+
$options = get_option( $this->optionname );
|
861 |
+
unset( $options['ga_token'] );
|
862 |
+
unset( $options['gawp_oauth']['access_token'] );
|
863 |
+
$options['gawp_oauth']['oauth_token'] = $request_token['oauth_token'];
|
864 |
+
$options['gawp_oauth']['oauth_token_secret'] = $request_token['oauth_token_secret'];
|
865 |
+
update_option( $this->optionname, $options );
|
866 |
+
|
867 |
+
wp_redirect( $gdata->get_authorize_url( $request_token ) );
|
868 |
+
exit;
|
869 |
+
}
|
870 |
+
|
871 |
+
} //end reauthenticate()
|
872 |
+
} // end class GA_Admin
|
873 |
+
|
874 |
+
$ga_admin = new GA_Admin();
|
875 |
+
} //endif
|
876 |
+
|
877 |
+
|
878 |
+
/**
|
879 |
+
* Code that actually inserts stuff into pages.
|
880 |
+
*/
|
881 |
+
if ( ! class_exists( 'GA_Filter' ) ) {
|
882 |
+
class GA_Filter {
|
883 |
+
|
884 |
+
/**
|
885 |
+
* Cleans the variable to make it ready for storing in Google Analytics
|
886 |
+
*/
|
887 |
+
function ga_str_clean($val) {
|
888 |
+
return remove_accents(str_replace('---','-',str_replace(' ','-',strtolower(html_entity_decode($val)))));
|
889 |
+
}
|
890 |
+
/*
|
891 |
+
* Insert the tracking code into the page
|
892 |
+
*/
|
893 |
+
function spool_analytics() {
|
894 |
+
global $wp_query;
|
895 |
+
// echo '<!--'.print_r($wp_query,1).'-->';
|
896 |
+
|
897 |
+
$options = get_option('Yoast_Google_Analytics');
|
898 |
+
|
899 |
+
if ( !isset($options['uastring']) || $options['uastring'] == '' ) {
|
900 |
+
if ( current_user_can('manage_options') )
|
901 |
+
echo "<!-- Google Analytics tracking code not shown because yo haven't chosen a Google Analytics account yet. -->\n";
|
902 |
+
return;
|
903 |
+
}
|
904 |
+
|
905 |
+
/**
|
906 |
+
* The order of custom variables is very, very important: custom vars should always take up the same slot to make analysis easy.
|
907 |
+
*/
|
908 |
+
$customvarslot = 1;
|
909 |
+
if ( yoast_ga_do_tracking() && !is_preview() ) {
|
910 |
+
$push = array();
|
911 |
+
|
912 |
+
if ( $options['allowanchor'] )
|
913 |
+
$push[] = "'_setAllowAnchor',true";
|
914 |
+
|
915 |
+
if ( $options['allowlinker'] )
|
916 |
+
$push[] = "'_setAllowLinker',true";
|
917 |
+
|
918 |
+
if ( $options['anonymizeip'] )
|
919 |
+
$push[] = "'_gat._anonymizeIp'";
|
920 |
+
|
921 |
+
if ( isset($options['domain']) && $options['domain'] != "" )
|
922 |
+
$push[] = "'_setDomainName','".$options['domain']."'";
|
923 |
+
|
924 |
+
if ( $options['trackcrossdomain'] )
|
925 |
+
$push[] = "'_setDomainName','".$options['primarycrossdomain']."'";
|
926 |
+
|
927 |
+
if ( $options['allowhash'] )
|
928 |
+
$push[] = "'_setAllowHash',false";
|
929 |
+
|
930 |
+
if ( $options['cv_loggedin'] ) {
|
931 |
+
$current_user = wp_get_current_user();
|
932 |
+
if ( $current_user && $current_user->ID != 0 )
|
933 |
+
$push[] = "'_setCustomVar',$customvarslot,'logged-in','".$current_user->roles[0]."',1";
|
934 |
+
// Customvar slot needs to be upped even when the user is not logged in, to make sure the variables below are always in the same slot.
|
935 |
+
$customvarslot++;
|
936 |
+
}
|
937 |
+
|
938 |
+
if ( function_exists('is_post_type_archive') && is_post_type_archive() ) {
|
939 |
+
if ( $options['cv_post_type'] ) {
|
940 |
+
$post_type = get_post_type();
|
941 |
+
if ( $post_type ) {
|
942 |
+
$push[] = "'_setCustomVar',".$customvarslot.",'post_type','".$post_type."',3";
|
943 |
+
$customvarslot++;
|
944 |
+
}
|
945 |
+
}
|
946 |
+
} else if ( is_singular() && !is_home() ) {
|
947 |
+
if ( $options['cv_post_type'] ) {
|
948 |
+
$post_type = get_post_type();
|
949 |
+
if ( $post_type ) {
|
950 |
+
$push[] = "'_setCustomVar',".$customvarslot.",'post_type','".$post_type."',3";
|
951 |
+
$customvarslot++;
|
952 |
+
}
|
953 |
+
}
|
954 |
+
if ( $options['cv_authorname'] ) {
|
955 |
+
$push[] = "'_setCustomVar',$customvarslot,'author','".GA_Filter::ga_str_clean(get_the_author_meta('display_name',$wp_query->post->post_author))."',3";
|
956 |
+
$customvarslot++;
|
957 |
+
}
|
958 |
+
if ( $options['cv_tags'] ) {
|
959 |
+
$i = 0;
|
960 |
+
if ( get_the_tags() ) {
|
961 |
+
$tagsstr = '';
|
962 |
+
foreach ( get_the_tags() as $tag ) {
|
963 |
+
if ($i > 0)
|
964 |
+
$tagsstr .= ' ';
|
965 |
+
$tagsstr .= $tag->slug;
|
966 |
+
$i++;
|
967 |
+
}
|
968 |
+
// Max 64 chars for value and label combined, hence 64 - 4
|
969 |
+
$tagsstr = substr($tagsstr, 0, 60);
|
970 |
+
$push[] = "'_setCustomVar',$customvarslot,'tags','".$tagsstr."',3";
|
971 |
+
}
|
972 |
+
$customvarslot++;
|
973 |
+
}
|
974 |
+
if ( is_singular() ) {
|
975 |
+
if ( $options['cv_year'] ) {
|
976 |
+
$push[] = "'_setCustomVar',$customvarslot,'year','".get_the_time('Y')."',3";
|
977 |
+
$customvarslot++;
|
978 |
+
}
|
979 |
+
if ( $options['cv_category'] && is_single() ) {
|
980 |
+
$cats = get_the_category();
|
981 |
+
if ( is_array( $cats ) && isset( $cats[0] ) )
|
982 |
+
$push[] = "'_setCustomVar',$customvarslot,'category','".$cats[0]->slug."',3";
|
983 |
+
$customvarslot++;
|
984 |
+
}
|
985 |
+
if ( $options['cv_all_categories'] && is_single() ) {
|
986 |
+
$i = 0;
|
987 |
+
$catsstr = '';
|
988 |
+
foreach ( (array) get_the_category() as $cat ) {
|
989 |
+
if ($i > 0)
|
990 |
+
$catsstr .= ' ';
|
991 |
+
$catsstr .= $cat->slug;
|
992 |
+
$i++;
|
993 |
+
}
|
994 |
+
// Max 64 chars for value and label combined, hence 64 - 10
|
995 |
+
$catsstr = substr($catsstr, 0, 54);
|
996 |
+
$push[] = "'_setCustomVar',$customvarslot,'categories','".$catsstr."',3";
|
997 |
+
$customvarslot++;
|
998 |
+
}
|
999 |
+
}
|
1000 |
+
}
|
1001 |
+
|
1002 |
+
$push = apply_filters('yoast-ga-custom-vars',$push, $customvarslot);
|
1003 |
+
|
1004 |
+
$push = apply_filters('yoast-ga-push-before-pageview',$push);
|
1005 |
+
|
1006 |
+
if ( is_404() ) {
|
1007 |
+
$push[] = "'_trackPageview','/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
|
1008 |
+
} else if ($wp_query->is_search) {
|
1009 |
+
$pushstr = "'_trackPageview','".get_bloginfo('url')."/?s=";
|
1010 |
+
if ($wp_query->found_posts == 0) {
|
1011 |
+
$push[] = $pushstr."no-results:".rawurlencode($wp_query->query_vars['s'])."&cat=no-results'";
|
1012 |
+
} else if ($wp_query->found_posts == 1) {
|
1013 |
+
$push[] = $pushstr.rawurlencode($wp_query->query_vars['s'])."&cat=1-result'";
|
1014 |
+
} else if ($wp_query->found_posts > 1 && $wp_query->found_posts < 6) {
|
1015 |
+
$push[] = $pushstr.rawurlencode($wp_query->query_vars['s'])."&cat=2-5-results'";
|
1016 |
+
} else {
|
1017 |
+
$push[] = $pushstr.rawurlencode($wp_query->query_vars['s'])."&cat=plus-5-results'";
|
1018 |
+
}
|
1019 |
+
} else {
|
1020 |
+
$push[] = "'_trackPageview'";
|
1021 |
+
}
|
1022 |
+
|
1023 |
+
if ( !isset( $options['disable_pagespeed_tracking'] ) || !$options['disable_pagespeed_tracking'] ) {
|
1024 |
+
$push[] = "'_trackPageLoadTime'";
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
$push = apply_filters('yoast-ga-push-after-pageview',$push);
|
1028 |
+
|
1029 |
+
if ( defined('WPSC_VERSION') && $options['wpec_tracking'] )
|
1030 |
+
$push = GA_Filter::wpec_transaction_tracking($push);
|
1031 |
+
|
1032 |
+
if ($options['shopp_tracking']) {
|
1033 |
+
global $Shopp;
|
1034 |
+
if ( isset($Shopp) )
|
1035 |
+
$push = GA_Filter::shopp_transaction_tracking($push);
|
1036 |
+
}
|
1037 |
+
|
1038 |
+
$pushstr = "";
|
1039 |
+
foreach ($push as $key) {
|
1040 |
+
if (!empty($pushstr))
|
1041 |
+
$pushstr .= ",";
|
1042 |
+
|
1043 |
+
$pushstr .= "[".$key."]";
|
1044 |
+
}
|
1045 |
+
|
1046 |
+
if ( current_user_can('manage_options') && $options['firebuglite'] && $options['debug'] )
|
1047 |
+
echo '<script src="https://getfirebug.com/firebug-lite.js" type="text/javascript"></script>';
|
1048 |
+
?>
|
1049 |
+
|
1050 |
+
<script type="text/javascript">//<![CDATA[
|
1051 |
+
// Google Analytics for WordPress by Yoast v<?php echo GAWP_VERSION; ?> | http://yoast.com/wordpress/google-analytics/
|
1052 |
+
var _gaq = _gaq || [];
|
1053 |
+
_gaq.push(['_setAccount','<?php echo trim($options["uastring"]); ?>']);
|
1054 |
+
<?php
|
1055 |
+
if ( $options["extrase"] ) {
|
1056 |
+
if ( !empty($options["extraseurl"]) ) {
|
1057 |
+
$url = $options["extraseurl"];
|
1058 |
+
} else {
|
1059 |
+
$url = plugins_url( 'custom_se_async.js', __FILE__ );
|
1060 |
+
}
|
1061 |
+
echo '</script><script src="'.$url.'" type="text/javascript"></script>'."\n".'<script type="text/javascript">';
|
1062 |
+
}
|
1063 |
+
|
1064 |
+
if ( $options['customcode'] && trim( $options['customcode'] ) != '' )
|
1065 |
+
echo "\t". stripslashes( $options['customcode'] ) ."\n";
|
1066 |
+
?>
|
1067 |
+
_gaq.push(<?php echo $pushstr; ?>);
|
1068 |
+
(function() {
|
1069 |
+
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
1070 |
+
ga.src = <?php
|
1071 |
+
if ( $options['gajslocalhosting'] && !empty($options['gajsurl']) ) {
|
1072 |
+
echo "'".$options['gajsurl']."';";
|
1073 |
+
} else {
|
1074 |
+
$script = 'ga.js';
|
1075 |
+
if ( current_user_can('manage_options') && $options['debug'] )
|
1076 |
+
$script = 'u/ga_debug.js';
|
1077 |
+
echo "('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/".$script."';";
|
1078 |
+
}
|
1079 |
+
?>
|
1080 |
+
|
1081 |
+
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
1082 |
+
})();
|
1083 |
+
//]]></script>
|
1084 |
+
<?php
|
1085 |
+
} else if ( $options["uastring"] != "" ) {
|
1086 |
+
echo "<!-- Google Analytics tracking code not shown because users over level ".$options["ignore_userlevel"]." are ignored -->\n";
|
1087 |
+
}
|
1088 |
+
}
|
1089 |
+
|
1090 |
+
/*
|
1091 |
+
* Insert the AdSense parameter code into the page. This'll go into the header per Google's instructions.
|
1092 |
+
*/
|
1093 |
+
function spool_adsense() {
|
1094 |
+
$options = get_option('Yoast_Google_Analytics');
|
1095 |
+
if ( $options["uastring"] != "" && yoast_ga_do_tracking() && !is_preview() ) {
|
1096 |
+
echo '<script type="text/javascript">'."\n";
|
1097 |
+
echo "\t".'window.google_analytics_uacct = "'.$options["uastring"].'";'."\n";
|
1098 |
+
echo '</script>'."\n";
|
1099 |
+
}
|
1100 |
+
}
|
1101 |
+
|
1102 |
+
function ga_get_tracking_prefix() {
|
1103 |
+
$options = get_option('Yoast_Google_Analytics');
|
1104 |
+
return (empty($options['trackprefix'])) ? '/yoast-ga/' : $options['trackprefix'];
|
1105 |
+
}
|
1106 |
+
|
1107 |
+
function ga_get_tracking_link($prefix, $target, $jsprefix = 'javascript:') {
|
1108 |
+
$options = get_option('Yoast_Google_Analytics');
|
1109 |
+
if (
|
1110 |
+
( $prefix != 'download' && $options['outboundpageview'] ) ||
|
1111 |
+
( $prefix == 'download' && $options['downloadspageview'] ) )
|
1112 |
+
{
|
1113 |
+
$prefix = GA_Filter::ga_get_tracking_prefix().$prefix;
|
1114 |
+
$pushstr = "['_trackPageview','".$prefix."/". esc_js( esc_url( $target ) )."']";
|
1115 |
+
} else {
|
1116 |
+
$pushstr = "['_trackEvent','".$prefix."','".esc_js( esc_url( $target ) )."']";
|
1117 |
+
}
|
1118 |
+
return $jsprefix."_gaq.push(".$pushstr.");";
|
1119 |
+
}
|
1120 |
+
|
1121 |
+
function ga_get_domain($uri){
|
1122 |
+
$hostPattern = "/^(http:\/\/)?([^\/]+)/i";
|
1123 |
+
$domainPatternUS = "/[^\.\/]+\.[^\.\/]+$/";
|
1124 |
+
$domainPatternUK = "/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/";
|
1125 |
+
|
1126 |
+
preg_match($hostPattern, $uri, $matches);
|
1127 |
+
$host = $matches[2];
|
1128 |
+
if (preg_match("/.*\..*\..*\..*$/",$host))
|
1129 |
+
preg_match($domainPatternUK, $host, $matches);
|
1130 |
+
else
|
1131 |
+
preg_match($domainPatternUS, $host, $matches);
|
1132 |
+
|
1133 |
+
return array("domain"=>$matches[0],"host"=>$host);
|
1134 |
+
}
|
1135 |
+
|
1136 |
+
function ga_parse_link($category, $matches){
|
1137 |
+
$origin = GA_Filter::ga_get_domain($_SERVER["HTTP_HOST"]);
|
1138 |
+
$options = get_option('Yoast_Google_Analytics');
|
1139 |
+
|
1140 |
+
// Break out immediately if the link is not an http or https link.
|
1141 |
+
if (strpos($matches[2],"http") !== 0) {
|
1142 |
+
$target = false;
|
1143 |
+
} else if ((strpos($matches[2],"mailto") === 0)) {
|
1144 |
+
$target = 'email';
|
1145 |
+
} else {
|
1146 |
+
$target = GA_Filter::ga_get_domain($matches[3]);
|
1147 |
+
}
|
1148 |
+
$trackBit = "";
|
1149 |
+
$extension = substr(strrchr($matches[3], '.'), 1);
|
1150 |
+
$dlextensions = explode(",",str_replace('.','',$options['dlextensions']));
|
1151 |
+
if ( $target ) {
|
1152 |
+
if ( $target == 'email' ) {
|
1153 |
+
$trackBit = GA_Filter::ga_get_tracking_link('mailto', str_replace('mailto:','',$matches[3]),'');
|
1154 |
+
} else if ( in_array($extension, $dlextensions) ) {
|
1155 |
+
$trackBit = GA_Filter::ga_get_tracking_link('download', $matches[3],'');
|
1156 |
+
} else if ( $target["domain"] != $origin["domain"] ){
|
1157 |
+
$crossdomains = explode(',',str_replace(' ','',$options['othercrossdomains']));
|
1158 |
+
if ( $options['trackcrossdomain'] && in_array($target["host"],$crossdomains) ) {
|
1159 |
+
$trackBit = '_gaq.push([\'_link\', \'' . $matches[2] . '//' . $matches[3] . '\']); return false;"';
|
1160 |
+
} else if ( $options['trackoutbound'] && in_array($options['domainorurl'], array('domain','url')) ) {
|
1161 |
+
$url = $options['domainorurl'] == 'domain' ? $target["host"] : $matches[3];
|
1162 |
+
$trackBit = GA_Filter::ga_get_tracking_link($category, $url,'');
|
1163 |
+
}
|
1164 |
+
$trackBit = GA_Filter::ga_get_tracking_link($category, $url,'');
|
1165 |
+
} else if ( $target["domain"] == $origin["domain"] && isset($options['internallink']) && $options['internallink'] != '') {
|
1166 |
+
$url = preg_replace('|'.$origin["host"].'|','',$matches[3]);
|
1167 |
+
$extintlinks = explode(',',$options['internallink']);
|
1168 |
+
foreach ($extintlinks as $link) {
|
1169 |
+
if (preg_match('|^'.trim($link).'|', $url, $match)) {
|
1170 |
+
$label = $options['internallinklabel'];
|
1171 |
+
if ($label == '')
|
1172 |
+
$label = 'int';
|
1173 |
+
$trackBit = GA_Filter::ga_get_tracking_link($category.'-'.$label, $url,'');
|
1174 |
+
}
|
1175 |
+
}
|
1176 |
+
}
|
1177 |
+
}
|
1178 |
+
if ($trackBit != "") {
|
1179 |
+
if (preg_match('/onclick=[\'\"](.*?)[\'\"]/i', $matches[4]) > 0) {
|
1180 |
+
// Check for manually tagged outbound clicks, and replace them with the tracking of choice.
|
1181 |
+
if (preg_match('/.*_track(Pageview|Event).*/i', $matches[4]) > 0) {
|
1182 |
+
$matches[4] = preg_replace('/onclick=[\'\"](javascript:)?(.*;)?[a-zA-Z0-9]+\._track(Pageview|Event)\([^\)]+\)(;)?(.*)?[\'\"]/i', 'onclick="javascript:' . $trackBit .'$2$5"', $matches[4]);
|
1183 |
+
} else {
|
1184 |
+
$matches[4] = preg_replace('/onclick=[\'\"](javascript:)?(.*?)[\'\"]/i', 'onclick="javascript:' . $trackBit .'$2"', $matches[4]);
|
1185 |
+
}
|
1186 |
+
} else {
|
1187 |
+
$matches[4] = 'onclick="javascript:' . $trackBit . '"' . $matches[4];
|
1188 |
+
}
|
1189 |
+
}
|
1190 |
+
return '<a ' . $matches[1] . 'href="' . $matches[2] . '//' . $matches[3] . '"' . ' ' . $matches[4] . '>' . $matches[5] . '</a>';
|
1191 |
+
}
|
1192 |
+
|
1193 |
+
function ga_parse_article_link($matches){
|
1194 |
+
return GA_Filter::ga_parse_link('outbound-article',$matches);
|
1195 |
+
}
|
1196 |
+
|
1197 |
+
function ga_parse_comment_link($matches){
|
1198 |
+
return GA_Filter::ga_parse_link('outbound-comment',$matches);
|
1199 |
+
}
|
1200 |
+
|
1201 |
+
function ga_parse_widget_link($matches){
|
1202 |
+
return GA_Filter::ga_parse_link('outbound-widget',$matches);
|
1203 |
+
}
|
1204 |
+
|
1205 |
+
function ga_parse_nav_menu($matches){
|
1206 |
+
return GA_Filter::ga_parse_link('outbound-menu',$matches);
|
1207 |
+
}
|
1208 |
+
|
1209 |
+
function widget_content($text) {
|
1210 |
+
if ( !yoast_ga_do_tracking() )
|
1211 |
+
return $text;
|
1212 |
+
static $anchorPattern = '/<a (.*?)href=[\'\"](.*?)\/\/([^\'\"]+?)[\'\"](.*?)>(.*?)<\/a>/i';
|
1213 |
+
$text = preg_replace_callback($anchorPattern,array('GA_Filter','ga_parse_widget_link'),$text);
|
1214 |
+
return $text;
|
1215 |
+
}
|
1216 |
+
|
1217 |
+
function the_content($text) {
|
1218 |
+
if ( !yoast_ga_do_tracking() )
|
1219 |
+
return $text;
|
1220 |
+
|
1221 |
+
if (!is_feed()) {
|
1222 |
+
static $anchorPattern = '/<a (.*?)href=[\'\"](.*?)\/\/([^\'\"]+?)[\'\"](.*?)>(.*?)<\/a>/i';
|
1223 |
+
$text = preg_replace_callback($anchorPattern,array('GA_Filter','ga_parse_article_link'),$text);
|
1224 |
+
}
|
1225 |
+
return $text;
|
1226 |
+
}
|
1227 |
+
|
1228 |
+
function nav_menu($text) {
|
1229 |
+
if ( !yoast_ga_do_tracking() )
|
1230 |
+
return $text;
|
1231 |
+
|
1232 |
+
if (!is_feed()) {
|
1233 |
+
static $anchorPattern = '/<a (.*?)href=[\'\"](.*?)\/\/([^\'\"]+?)[\'\"](.*?)>(.*?)<\/a>/i';
|
1234 |
+
$text = preg_replace_callback($anchorPattern,array('GA_Filter','ga_parse_nav_menu'),$text);
|
1235 |
+
}
|
1236 |
+
return $text;
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
function comment_text($text) {
|
1240 |
+
if ( !yoast_ga_do_tracking() )
|
1241 |
+
return $text;
|
1242 |
+
|
1243 |
+
if (!is_feed()) {
|
1244 |
+
static $anchorPattern = '/<a (.*?)href="(.*?)\/\/(.*?)"(.*?)>(.*?)<\/a>/i';
|
1245 |
+
$text = preg_replace_callback($anchorPattern,array('GA_Filter','ga_parse_comment_link'),$text);
|
1246 |
+
}
|
1247 |
+
return $text;
|
1248 |
+
}
|
1249 |
+
|
1250 |
+
function comment_author_link($text) {
|
1251 |
+
$options = get_option('Yoast_Google_Analytics');
|
1252 |
+
|
1253 |
+
if ( !yoast_ga_do_tracking() )
|
1254 |
+
return $text;
|
1255 |
+
|
1256 |
+
static $anchorPattern = '/(.*\s+.*?href\s*=\s*)["\'](.*?)["\'](.*)/';
|
1257 |
+
preg_match($anchorPattern, $text, $matches);
|
1258 |
+
if ($matches[2] == "") return $text;
|
1259 |
+
|
1260 |
+
$trackBit = '';
|
1261 |
+
$target = GA_Filter::ga_get_domain($matches[2]);
|
1262 |
+
$origin = GA_Filter::ga_get_domain($_SERVER["HTTP_HOST"]);
|
1263 |
+
if ( $target["domain"] != $origin["domain"] ){
|
1264 |
+
if ( isset( $options['domainorurl'] ) && $options['domainorurl'] == "domain" )
|
1265 |
+
$url = $target["host"];
|
1266 |
+
else
|
1267 |
+
$url = $matches[2];
|
1268 |
+
$trackBit = 'onclick="'.GA_Filter::ga_get_tracking_link('outbound-commentauthor', $url).'"';
|
1269 |
+
}
|
1270 |
+
return $matches[1] . "\"" . $matches[2] . "\" " . $trackBit ." ". $matches[3];
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
function bookmarks($bookmarks) {
|
1274 |
+
if ( !yoast_ga_do_tracking() )
|
1275 |
+
return $bookmarks;
|
1276 |
+
|
1277 |
+
$i = 0;
|
1278 |
+
while ( $i < count($bookmarks) ) {
|
1279 |
+
$target = GA_Filter::ga_get_domain($bookmarks[$i]->link_url);
|
1280 |
+
$sitedomain = GA_Filter::ga_get_domain(get_bloginfo('url'));
|
1281 |
+
if ($target['host'] == $sitedomain['host']) {
|
1282 |
+
$i++;
|
1283 |
+
continue;
|
1284 |
+
}
|
1285 |
+
if ( isset( $options['domainorurl'] ) && $options['domainorurl'] == "domain" )
|
1286 |
+
$url = $target["host"];
|
1287 |
+
else
|
1288 |
+
$url = $bookmarks[$i]->link_url;
|
1289 |
+
$trackBit = '" onclick="'.GA_Filter::ga_get_tracking_link('outbound-blogroll', $url);
|
1290 |
+
$bookmarks[$i]->link_target .= $trackBit;
|
1291 |
+
$i++;
|
1292 |
+
}
|
1293 |
+
return $bookmarks;
|
1294 |
+
}
|
1295 |
+
|
1296 |
+
function rsslinktagger($guid) {
|
1297 |
+
$options = get_option('Yoast_Google_Analytics');
|
1298 |
+
global $wp, $post;
|
1299 |
+
if ( is_feed() ) {
|
1300 |
+
if ( $options['allowanchor'] ) {
|
1301 |
+
$delimiter = '#';
|
1302 |
+
} else {
|
1303 |
+
$delimiter = '?';
|
1304 |
+
if (strpos ( $guid, $delimiter ) > 0)
|
1305 |
+
$delimiter = '&';
|
1306 |
+
}
|
1307 |
+
return $guid . $delimiter . 'utm_source=rss&utm_medium=rss&utm_campaign='.urlencode($post->post_name);
|
1308 |
+
}
|
1309 |
+
return $guid;
|
1310 |
+
}
|
1311 |
+
|
1312 |
+
function wpec_transaction_tracking( $push ) {
|
1313 |
+
global $wpdb, $purchlogs, $cart_log_id;
|
1314 |
+
if( !isset( $cart_log_id ) || empty($cart_log_id) )
|
1315 |
+
return $push;
|
1316 |
+
|
1317 |
+
$city = $wpdb->get_var ("SELECT tf.value
|
1318 |
+
FROM ".WPSC_TABLE_SUBMITED_FORM_DATA." tf
|
1319 |
+
LEFT JOIN ".WPSC_TABLE_CHECKOUT_FORMS." cf
|
1320 |
+
ON cf.id = tf.form_id
|
1321 |
+
WHERE cf.type = 'city'
|
1322 |
+
AND log_id = ".$cart_log_id );
|
1323 |
+
|
1324 |
+
$country = $wpdb->get_var ("SELECT tf.value
|
1325 |
+
FROM ".WPSC_TABLE_SUBMITED_FORM_DATA." tf
|
1326 |
+
LEFT JOIN ".WPSC_TABLE_CHECKOUT_FORMS." cf
|
1327 |
+
ON cf.id = tf.form_id
|
1328 |
+
WHERE cf.type = 'country'
|
1329 |
+
AND log_id = ".$cart_log_id );
|
1330 |
+
|
1331 |
+
$cart_items = $wpdb->get_results ("SELECT * FROM ".WPSC_TABLE_CART_CONTENTS." WHERE purchaseid = ".$cart_log_id, ARRAY_A);
|
1332 |
+
|
1333 |
+
$total_shipping = $purchlogs->allpurchaselogs[0]->base_shipping;
|
1334 |
+
$total_tax = 0;
|
1335 |
+
foreach ( $cart_items as $item ) {
|
1336 |
+
$total_shipping += $item['pnp'];
|
1337 |
+
$total_tax += $item['tax_charged'];
|
1338 |
+
}
|
1339 |
+
|
1340 |
+
$push[] = "'_addTrans','".$cart_log_id."'," // Order ID
|
1341 |
+
."'".GA_Filter::ga_str_clean(get_bloginfo('name'))."'," // Store name
|
1342 |
+
."'".nzshpcrt_currency_display($purchlogs->allpurchaselogs[0]->totalprice,1,true,false,true)."'," // Total price
|
1343 |
+
."'".nzshpcrt_currency_display($total_tax,1,true,false,true)."'," // Tax
|
1344 |
+
."'".nzshpcrt_currency_display($total_shipping,1,true,false,true)."'," // Shipping
|
1345 |
+
."'".$city."'," // City
|
1346 |
+
."''," // State
|
1347 |
+
."'".$country."'"; // Country
|
1348 |
+
|
1349 |
+
foreach( $cart_items as $item ) {
|
1350 |
+
$item['sku'] = $wpdb->get_var( "SELECT meta_value FROM ".WPSC_TABLE_PRODUCTMETA." WHERE meta_key = 'sku' AND product_id = '".$item['prodid']."' LIMIT 1" );
|
1351 |
+
|
1352 |
+
$item['category'] = $wpdb->get_var( "SELECT pc.name FROM ".WPSC_TABLE_PRODUCT_CATEGORIES." pc LEFT JOIN ".WPSC_TABLE_ITEM_CATEGORY_ASSOC." ca ON pc.id = ca.category_id WHERE pc.group_id = '1' AND ca.product_id = '".$item['prodid']."'" );
|
1353 |
+
$push[] = "'_addItem',"
|
1354 |
+
."'".$cart_log_id."'," // Order ID
|
1355 |
+
."'".$item['sku']."'," // Item SKU
|
1356 |
+
."'". str_replace( "'", "", $item['name'] ) ."'," // Item Name
|
1357 |
+
."'".$item['category']."'," // Item Category
|
1358 |
+
."'".$item['price']."'," // Item Price
|
1359 |
+
."'".$item['quantity']."'"; // Item Quantity
|
1360 |
+
}
|
1361 |
+
$push[] = "'_trackTrans'";
|
1362 |
+
|
1363 |
+
return $push;
|
1364 |
+
}
|
1365 |
+
|
1366 |
+
function shopp_transaction_tracking( $push ) {
|
1367 |
+
global $Shopp;
|
1368 |
+
|
1369 |
+
// Only process if we're in the checkout process (receipt page)
|
1370 |
+
if (version_compare(substr(SHOPP_VERSION,0,3),'1.1') >= 0) {
|
1371 |
+
// Only process if we're in the checkout process (receipt page)
|
1372 |
+
if (function_exists('is_shopp_page') && !is_shopp_page('checkout')) return $push;
|
1373 |
+
if (empty($Shopp->Order->purchase)) return $push;
|
1374 |
+
|
1375 |
+
$Purchase = new Purchase($Shopp->Order->purchase);
|
1376 |
+
$Purchase->load_purchased();
|
1377 |
+
} else {
|
1378 |
+
// For 1.0.x
|
1379 |
+
// Only process if we're in the checkout process (receipt page)
|
1380 |
+
if (function_exists('is_shopp_page') && !is_shopp_page('checkout')) return $push;
|
1381 |
+
// Only process if we have valid order data
|
1382 |
+
if (!isset($Shopp->Cart->data->Purchase)) return $push;
|
1383 |
+
if (empty($Shopp->Cart->data->Purchase->id)) return $push;
|
1384 |
+
|
1385 |
+
$Purchase = $Shopp->Cart->data->Purchase;
|
1386 |
+
}
|
1387 |
+
|
1388 |
+
$push[] = "'_addTrans',"
|
1389 |
+
."'".$Purchase->id."'," // Order ID
|
1390 |
+
."'".GA_Filter::ga_str_clean(get_bloginfo('name'))."'," // Store
|
1391 |
+
."'".number_format($Purchase->total,2)."'," // Total price
|
1392 |
+
."'".number_format($Purchase->tax,2)."'," // Tax
|
1393 |
+
."'".number_format($Purchase->shipping,2)."'," // Shipping
|
1394 |
+
."'".$Purchase->city."'," // City
|
1395 |
+
."'".$Purchase->state."'," // State
|
1396 |
+
."'.$Purchase->country.'"; // Country
|
1397 |
+
|
1398 |
+
foreach ($Purchase->purchased as $item) {
|
1399 |
+
$sku = empty($item->sku) ? 'PID-'.$item->product.str_pad($item->price,4,'0',STR_PAD_LEFT) : $item->sku;
|
1400 |
+
$push[] = "'_addItem',"
|
1401 |
+
."'".$Purchase->id."',"
|
1402 |
+
."'".$sku."',"
|
1403 |
+
."'". str_replace( "'", "", $item->name ) ."',"
|
1404 |
+
."'".$item->optionlabel."',"
|
1405 |
+
."'".number_format($item->unitprice,2)."',"
|
1406 |
+
."'".$item->quantity."'";
|
1407 |
+
}
|
1408 |
+
$push[] = "'_trackTrans'";
|
1409 |
+
return $push;
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
} // class GA_Filter
|
1413 |
+
} // endif
|
1414 |
+
|
1415 |
+
/**
|
1416 |
+
* If setAllowAnchor is set to true, GA ignores all links tagged "normally", so we redirect all "normally" tagged URL's
|
1417 |
+
* to one tagged with a hash.
|
1418 |
+
*/
|
1419 |
+
function ga_utm_hashtag_redirect() {
|
1420 |
+
if (isset($_SERVER['REQUEST_URI'])) {
|
1421 |
+
if (strpos($_SERVER['REQUEST_URI'], "utm_") !== false) {
|
1422 |
+
$url = 'http://';
|
1423 |
+
if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != "") {
|
1424 |
+
$url = 'https://';
|
1425 |
+
}
|
1426 |
+
$url .= $_SERVER['SERVER_NAME'];
|
1427 |
+
if ( strpos($_SERVER['REQUEST_URI'], "?utm_") !== false ) {
|
1428 |
+
$url .= str_replace("?utm_","#utm_",$_SERVER['REQUEST_URI']);
|
1429 |
+
} else if ( strpos($_SERVER['REQUEST_URI'], "&utm_") !== false ) {
|
1430 |
+
$url .= substr_replace($_SERVER['REQUEST_URI'], "#utm_", strpos($_SERVER['REQUEST_URI'], "&utm_"), 5);
|
1431 |
+
}
|
1432 |
+
wp_redirect($url, 301);
|
1433 |
+
exit;
|
1434 |
+
}
|
1435 |
+
}
|
1436 |
+
}
|
1437 |
+
|
1438 |
+
function yoast_ga_do_tracking() {
|
1439 |
+
$current_user = wp_get_current_user();
|
1440 |
+
|
1441 |
+
if (0 == $current_user->ID)
|
1442 |
+
return true;
|
1443 |
+
|
1444 |
+
$yoast_ga_options = get_option('Yoast_Google_Analytics');
|
1445 |
+
|
1446 |
+
if ( ($current_user->user_level >= $yoast_ga_options["ignore_userlevel"]) )
|
1447 |
+
return false;
|
1448 |
+
else
|
1449 |
+
return true;
|
1450 |
+
}
|
1451 |
+
|
1452 |
+
function track_comment_form_head() {
|
1453 |
+
if (is_singular()) {
|
1454 |
+
global $post;
|
1455 |
+
$yoast_ga_options = get_option('Yoast_Google_Analytics');
|
1456 |
+
if ( yoast_ga_do_tracking()
|
1457 |
+
&& isset( $yoast_ga_options["trackcommentform"] )
|
1458 |
+
&& $yoast_ga_options["trackcommentform"]
|
1459 |
+
&& ( 'open' == $post->comment_status ) )
|
1460 |
+
wp_enqueue_script('jquery');
|
1461 |
+
}
|
1462 |
+
}
|
1463 |
+
add_action('wp_print_scripts','track_comment_form_head');
|
1464 |
+
|
1465 |
+
$comment_form_id = '';
|
1466 |
+
function yoast_get_comment_form_id($args) {
|
1467 |
+
global $comment_form_id;
|
1468 |
+
$comment_form_id = $args['id_form'];
|
1469 |
+
return $args;
|
1470 |
+
}
|
1471 |
+
add_filter('comment_form_defaults', 'yoast_get_comment_form_id',99,1);
|
1472 |
+
|
1473 |
+
function yoast_track_comment_form() {
|
1474 |
+
global $comment_form_id, $post;
|
1475 |
+
$yoast_ga_options = get_option('Yoast_Google_Analytics');
|
1476 |
+
if ( yoast_ga_do_tracking() && $yoast_ga_options["trackcommentform"] ) {
|
1477 |
+
?>
|
1478 |
+
<script type="text/javascript">
|
1479 |
+
jQuery(document).ready(function() {
|
1480 |
+
jQuery('#<?php echo $comment_form_id; ?>').submit(function() {
|
1481 |
+
_gaq.push(
|
1482 |
+
['_setAccount','<?php echo $yoast_ga_options["uastring"]; ?>'],
|
1483 |
+
['_trackEvent','comment']
|
1484 |
+
);
|
1485 |
+
});
|
1486 |
+
});
|
1487 |
+
</script>
|
1488 |
+
<?php
|
1489 |
+
}
|
1490 |
+
}
|
1491 |
+
add_action('comment_form_after','yoast_track_comment_form');
|
1492 |
+
|
1493 |
+
function yoast_sanitize_relative_links($content) {
|
1494 |
+
preg_match("|^http(s)?://([^/]+)|i", get_bloginfo('url'), $match);
|
1495 |
+
$content = preg_replace("/<a([^>]*) href=('|\")\/([^\"']*)('|\")/", "<a\${1} href=\"" .$match[0] ."/" ."\${3}\"", $content);
|
1496 |
+
|
1497 |
+
if (is_singular()) {
|
1498 |
+
$content = preg_replace("/<a([^>]*) href=('|\")#([^\"']*)('|\")/", "<a\${1} href=\"" .get_permalink()."#" ."\${3}\"", $content);
|
1499 |
+
}
|
1500 |
+
return $content;
|
1501 |
+
}
|
1502 |
+
add_filter('the_content', 'yoast_sanitize_relative_links', 98);
|
1503 |
+
add_filter('widget_text', 'yoast_sanitize_relative_links', 98);
|
1504 |
+
|
1505 |
+
function yoast_analytics() {
|
1506 |
+
$options = get_option('Yoast_Google_Analytics');
|
1507 |
+
if ($options['position'] == 'manual')
|
1508 |
+
GA_Filter::spool_analytics();
|
1509 |
+
else
|
1510 |
+
echo '<!-- Please set Google Analytics position to "manual" in the settings, or remove this call to yoast_analytics(); -->';
|
1511 |
+
}
|
1512 |
+
|
1513 |
+
$gaf = new GA_Filter();
|
1514 |
+
$options = get_option('Yoast_Google_Analytics');
|
1515 |
+
|
1516 |
+
if (!is_array($options)) {
|
1517 |
+
$options = get_option('GoogleAnalyticsPP');
|
1518 |
+
if (!is_array($options)) {
|
1519 |
+
$ga_admin->set_defaults();
|
1520 |
+
} else {
|
1521 |
+
delete_option('GoogleAnalyticsPP');
|
1522 |
+
if ($options['admintracking']) {
|
1523 |
+
$options["ignore_userlevel"] = '8';
|
1524 |
+
unset($options['admintracking']);
|
1525 |
+
} else {
|
1526 |
+
$options["ignore_userlevel"] = '11';
|
1527 |
+
}
|
1528 |
+
update_option('Yoast_Google_Analytics', $options);
|
1529 |
+
}
|
1530 |
+
} else {
|
1531 |
+
if ( isset( $options['allowanchor'] ) && $options['allowanchor'] ) {
|
1532 |
+
add_action('init','ga_utm_hashtag_redirect',1);
|
1533 |
+
}
|
1534 |
+
|
1535 |
+
if ( (isset( $options['trackoutbound'] ) && $options['trackoutbound'] ) ||
|
1536 |
+
(isset( $options['trackcrossdomain'] ) && $options['trackcrossdomain'] ) ) {
|
1537 |
+
// filters alter the existing content
|
1538 |
+
add_filter('the_content', array('GA_Filter','the_content'), 99);
|
1539 |
+
add_filter('widget_text', array('GA_Filter','widget_content'), 99);
|
1540 |
+
add_filter('the_excerpt', array('GA_Filter','the_content'), 99);
|
1541 |
+
add_filter('comment_text', array('GA_Filter','comment_text'), 99);
|
1542 |
+
add_filter('get_bookmarks', array('GA_Filter','bookmarks'), 99);
|
1543 |
+
add_filter('get_comment_author_link', array('GA_Filter','comment_author_link'), 99);
|
1544 |
+
add_filter('wp_nav_menu', array('GA_Filter','nav_menu'), 99);
|
1545 |
+
}
|
1546 |
+
|
1547 |
+
if ( isset( $options['trackadsense'] ) && $options['trackadsense'] )
|
1548 |
+
add_action('wp_head', array('GA_Filter','spool_adsense'),1);
|
1549 |
+
|
1550 |
+
if ( !isset( $options['position'] ) )
|
1551 |
+
$options['position'] = 'header';
|
1552 |
+
|
1553 |
+
switch ($options['position']) {
|
1554 |
+
case 'manual':
|
1555 |
+
// No need to insert here, bail NOW.
|
1556 |
+
break;
|
1557 |
+
case 'header':
|
1558 |
+
default:
|
1559 |
+
add_action('wp_head', array('GA_Filter','spool_analytics'),2);
|
1560 |
+
break;
|
1561 |
+
}
|
1562 |
+
|
1563 |
+
if ( isset( $options['trackregistration'] ) && $options['trackregistration'] )
|
1564 |
+
add_action('login_head', array('GA_Filter','spool_analytics'),20);
|
1565 |
+
|
1566 |
+
if ( isset( $options['rsslinktagging'] ) && $options['rsslinktagging'] )
|
1567 |
+
add_filter ( 'the_permalink_rss', array('GA_Filter','rsslinktagger'), 99 );
|
1568 |
+
|
1569 |
+
}
|
images/facebook-icon.png
ADDED
Binary file
|
images/google-plus-icon.png
ADDED
Binary file
|
images/twitter-icon.png
ADDED
Binary file
|
readme.txt
CHANGED
@@ -1,329 +1,335 @@
|
|
1 |
-
=== Google Analytics for WordPress ===
|
2 |
-
Contributors: joostdevalk
|
3 |
-
Donate link: http://yoast.com/donate/
|
4 |
-
Tags: analytics, google analytics, statistics, tracking, stats, google
|
5 |
-
Requires at least: 2.8
|
6 |
-
Tested up to: 3.2
|
7 |
-
Stable tag: 4.
|
8 |
-
|
9 |
-
Track your WordPress site easily and with lots of metadata: views per author & category, automatic tracking of outbound clicks and pageviews.
|
10 |
-
|
11 |
-
== Description ==
|
12 |
-
|
13 |
-
The Google Analytics for WordPress plugin allows you to track your blog easily and with lots of metadata.
|
14 |
-
|
15 |
-
Check out the [Google Analytics for WordPress video](http://www.youtube.com/watch?v=tnUXzbvXxSQ):
|
16 |
-
|
17 |
-
http://www.youtube.com/watch?v=tnUXzbvXxSQ&hd=1
|
18 |
-
|
19 |
-
Full list of features:
|
20 |
-
|
21 |
-
* Simple installation through integration with Google Analytics API: authenticate, select the site you want to track and you're done.
|
22 |
-
* This plugin uses the asynchronous Google Analytics tracking code, the fastest and most reliable tracking code Google Analytics offers.
|
23 |
-
* Option to manually place the tracking code in another location.
|
24 |
-
* Automatic Google Analytics site speed tracking.
|
25 |
-
* Outbound link & downloads tracking.
|
26 |
-
* Configurable options to track outbound links either as pageviews.
|
27 |
-
* Option to track just downloads as pageviews in Google Analytics.
|
28 |
-
* Allows usage of custom variables in Google Analytics to track meta data on pages. Support for the following custom variables:
|
29 |
-
* Author
|
30 |
-
* Single category and / or multiple categories
|
31 |
-
* Post type (especially useful if you use custom post types)
|
32 |
-
* Logged in users
|
33 |
-
* Publication Year
|
34 |
-
* Tags
|
35 |
-
* Possibility to ignore any user level and up, so all editors and higher for instance.
|
36 |
-
* Easily connect your Google AdSense and Google Analytics accounts.
|
37 |
-
* Option to tag links with Google Analytics campaign tracking, with the option to use hashes (#).
|
38 |
-
* Option anonymize IP's, for use in countries like Germany.
|
39 |
-
* Full [debug mode](http://yoast.com/google-analytics-debug-mode/), including Firebug lite and ga_debug.js for debugging Google Analytics issues.
|
40 |
-
* Allow local hosting of ga.js file.
|
41 |
-
* Tracking of search engines not included in Google Analytics default tracking.
|
42 |
-
* Tracking of login and registration forms.
|
43 |
-
|
44 |
-
Other interesting stuff:
|
45 |
-
|
46 |
-
* Check out the other [Wordpress plugins](http://yoast.com/wordpress/) by the same author.
|
47 |
-
* Want to increase traffic to your WordPress blog? Check out the [WordPress SEO](http://yoast.com/articles/wordpress-seo/) Guide!
|
48 |
-
* Check out the authors [WordPress Hosting](http://yoast.com/articles/wordpress-hosting/) experience. Good hosting is hard to come by, but it doesn't have to be expensive, Joost tells you why!
|
49 |
-
* If you've still not seen enough, or you'd rather listen than read, check out the [WordPress Podcast](http://wp-community.org/), hosted by the author of this plugin and Frederick Townes, the creator of [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/).
|
50 |
-
|
51 |
-
== Installation ==
|
52 |
-
|
53 |
-
This section describes how to install the plugin and get it working.
|
54 |
-
|
55 |
-
1. Delete any existing `gapp` or `google-analytics-for-wordpress` folder from the `/wp-content/plugins/` directory
|
56 |
-
1. Upload `google-analytics-for-wordpress` folder to the `/wp-content/plugins/` directory
|
57 |
-
1. Activate the plugin through the 'Plugins' menu in WordPress
|
58 |
-
1. Go to the options panel under the 'Settings' menu and add your Analytics account number and set the settings you want.
|
59 |
-
|
60 |
-
== Changelog ==
|
61 |
-
|
62 |
-
= 4.
|
63 |
-
|
64 |
-
*
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
*
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
*
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
*
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
*
|
99 |
-
*
|
100 |
-
*
|
101 |
-
|
102 |
-
= 4.0.
|
103 |
-
|
104 |
-
*
|
105 |
-
*
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
*
|
112 |
-
|
113 |
-
|
114 |
-
*
|
115 |
-
*
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
*
|
120 |
-
*
|
121 |
-
*
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
*
|
128 |
-
|
129 |
-
|
130 |
-
*
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
= 4.0.
|
136 |
-
* Bugs fixed in this release:
|
137 |
-
*
|
138 |
-
*
|
139 |
-
*
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
*
|
144 |
-
*
|
145 |
-
*
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
*
|
150 |
-
|
151 |
-
*
|
152 |
-
*
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
*
|
157 |
-
* Added
|
158 |
-
*
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
*
|
163 |
-
|
164 |
-
|
165 |
-
*
|
166 |
-
|
167 |
-
|
168 |
-
*
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
*
|
174 |
-
*
|
175 |
-
*
|
176 |
-
*
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
*
|
181 |
-
*
|
182 |
-
|
183 |
-
|
184 |
-
*
|
185 |
-
|
186 |
-
|
187 |
-
*
|
188 |
-
|
189 |
-
|
190 |
-
*
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
*
|
195 |
-
*
|
196 |
-
*
|
197 |
-
|
198 |
-
|
199 |
-
*
|
200 |
-
|
201 |
-
|
202 |
-
*
|
203 |
-
|
204 |
-
= 3.2.
|
205 |
-
*
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
= 3.2 =
|
211 |
-
*
|
212 |
-
*
|
213 |
-
*
|
214 |
-
*
|
215 |
-
|
216 |
-
= 3.
|
217 |
-
*
|
218 |
-
|
219 |
-
|
220 |
-
*
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
*
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
*
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
*
|
244 |
-
|
245 |
-
|
246 |
-
* Added
|
247 |
-
|
248 |
-
|
249 |
-
*
|
250 |
-
|
251 |
-
|
252 |
-
*
|
253 |
-
*
|
254 |
-
*
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
* Added
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
*
|
269 |
-
|
270 |
-
= 2.6.
|
271 |
-
*
|
272 |
-
|
273 |
-
= 2.6.
|
274 |
-
*
|
275 |
-
|
276 |
-
= 2.6 =
|
277 |
-
*
|
278 |
-
|
279 |
-
= 2.
|
280 |
-
* Fixed
|
281 |
-
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
|
286 |
-
|
287 |
-
*
|
288 |
-
|
289 |
-
= 2.
|
290 |
-
*
|
291 |
-
|
292 |
-
= 1
|
293 |
-
*
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
=== Google Analytics for WordPress ===
|
2 |
+
Contributors: joostdevalk
|
3 |
+
Donate link: http://yoast.com/donate/
|
4 |
+
Tags: analytics, google analytics, statistics, tracking, stats, google
|
5 |
+
Requires at least: 2.8
|
6 |
+
Tested up to: 3.2.1
|
7 |
+
Stable tag: 4.2
|
8 |
+
|
9 |
+
Track your WordPress site easily and with lots of metadata: views per author & category, automatic tracking of outbound clicks and pageviews.
|
10 |
+
|
11 |
+
== Description ==
|
12 |
+
|
13 |
+
The Google Analytics for WordPress plugin allows you to track your blog easily and with lots of metadata.
|
14 |
+
|
15 |
+
Check out the [Google Analytics for WordPress video](http://www.youtube.com/watch?v=tnUXzbvXxSQ):
|
16 |
+
|
17 |
+
http://www.youtube.com/watch?v=tnUXzbvXxSQ&hd=1
|
18 |
+
|
19 |
+
Full list of features:
|
20 |
+
|
21 |
+
* Simple installation through integration with Google Analytics API: authenticate, select the site you want to track and you're done.
|
22 |
+
* This plugin uses the asynchronous Google Analytics tracking code, the fastest and most reliable tracking code Google Analytics offers.
|
23 |
+
* Option to manually place the tracking code in another location.
|
24 |
+
* Automatic Google Analytics site speed tracking.
|
25 |
+
* Outbound link & downloads tracking.
|
26 |
+
* Configurable options to track outbound links either as pageviews.
|
27 |
+
* Option to track just downloads as pageviews in Google Analytics.
|
28 |
+
* Allows usage of custom variables in Google Analytics to track meta data on pages. Support for the following custom variables:
|
29 |
+
* Author
|
30 |
+
* Single category and / or multiple categories
|
31 |
+
* Post type (especially useful if you use custom post types)
|
32 |
+
* Logged in users
|
33 |
+
* Publication Year
|
34 |
+
* Tags
|
35 |
+
* Possibility to ignore any user level and up, so all editors and higher for instance.
|
36 |
+
* Easily connect your Google AdSense and Google Analytics accounts.
|
37 |
+
* Option to tag links with Google Analytics campaign tracking, with the option to use hashes (#).
|
38 |
+
* Option anonymize IP's, for use in countries like Germany.
|
39 |
+
* Full [debug mode](http://yoast.com/google-analytics-debug-mode/), including Firebug lite and ga_debug.js for debugging Google Analytics issues.
|
40 |
+
* Allow local hosting of ga.js file.
|
41 |
+
* Tracking of search engines not included in Google Analytics default tracking.
|
42 |
+
* Tracking of login and registration forms.
|
43 |
+
|
44 |
+
Other interesting stuff:
|
45 |
+
|
46 |
+
* Check out the other [Wordpress plugins](http://yoast.com/wordpress/) by the same author.
|
47 |
+
* Want to increase traffic to your WordPress blog? Check out the [WordPress SEO](http://yoast.com/articles/wordpress-seo/) Guide!
|
48 |
+
* Check out the authors [WordPress Hosting](http://yoast.com/articles/wordpress-hosting/) experience. Good hosting is hard to come by, but it doesn't have to be expensive, Joost tells you why!
|
49 |
+
* If you've still not seen enough, or you'd rather listen than read, check out the [WordPress Podcast](http://wp-community.org/), hosted by the author of this plugin and Frederick Townes, the creator of [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/).
|
50 |
+
|
51 |
+
== Installation ==
|
52 |
+
|
53 |
+
This section describes how to install the plugin and get it working.
|
54 |
+
|
55 |
+
1. Delete any existing `gapp` or `google-analytics-for-wordpress` folder from the `/wp-content/plugins/` directory
|
56 |
+
1. Upload `google-analytics-for-wordpress` folder to the `/wp-content/plugins/` directory
|
57 |
+
1. Activate the plugin through the 'Plugins' menu in WordPress
|
58 |
+
1. Go to the options panel under the 'Settings' menu and add your Analytics account number and set the settings you want.
|
59 |
+
|
60 |
+
== Changelog ==
|
61 |
+
|
62 |
+
= 4.2 =
|
63 |
+
|
64 |
+
* Google Authentication now happens using OAuth. The requests have become signed as an extra security measure and tokens have become more stable, as opposed to the prior tokens used with AuthSub.
|
65 |
+
* Added support for cross-domain tracking.
|
66 |
+
* Fixed various small bugs.
|
67 |
+
|
68 |
+
= 4.1.3 =
|
69 |
+
|
70 |
+
* Security fix: badly crafted comments could lead to insertion of "weird" links into comments. They'd have to pass your moderation, but still... Immediate update advised. Props to David Whitehouse and James Slater for finding it.
|
71 |
+
|
72 |
+
= 4.1.2 =
|
73 |
+
|
74 |
+
* Fixed bug with custom SE tracking introduced in 4.1.1.
|
75 |
+
|
76 |
+
= 4.1.1 =
|
77 |
+
|
78 |
+
* Made plugin admin work with jQuery 1.6 and jQuery 1.4.
|
79 |
+
* Added contextual help.
|
80 |
+
* Improved cache flushing when using W3TC.
|
81 |
+
* Fixed various minor other notices.
|
82 |
+
* First stab at getting ready for full i18n compatibility.
|
83 |
+
|
84 |
+
= 4.1 =
|
85 |
+
|
86 |
+
* Added:
|
87 |
+
* Google Site Speed tracking, turned it on by default.
|
88 |
+
|
89 |
+
* Fixed:
|
90 |
+
* Custom code now properly removes slashes.
|
91 |
+
|
92 |
+
= 4.0.12 =
|
93 |
+
|
94 |
+
* Fixed:
|
95 |
+
* Tons of notices in backend and front end when no settings were saved yet.
|
96 |
+
* Set proper defaults for all variables.
|
97 |
+
* Notice for unset categories array on custom post types.
|
98 |
+
* Notice for unset variable.
|
99 |
+
* Error when user is not logged in in certain corner cases.
|
100 |
+
* Bug where $options was used but never loaded for blogroll links.
|
101 |
+
|
102 |
+
= 4.0.11 =
|
103 |
+
|
104 |
+
* Bugs fixed:
|
105 |
+
* You can now disable comment form tracking properly.
|
106 |
+
* Removed charset property from script tags to allow validation with HTML5 doctype.
|
107 |
+
|
108 |
+
= 4.0.10 =
|
109 |
+
|
110 |
+
* Known issues:
|
111 |
+
* Authentication with Google gives errors in quite a few cases. Please use the manual option to add your UA code until we find a way to reliably fix it.
|
112 |
+
|
113 |
+
* Added functionality:
|
114 |
+
* Option to set `_setAllowHash` to false, for proper subdomain tracking and some other uses.
|
115 |
+
* Option to add a custom string of code to the tracking, before the push string is sent out.
|
116 |
+
|
117 |
+
* Documentation fixes:
|
118 |
+
* Fixed link for `_setDomainName()`.
|
119 |
+
* Fixed some grammatical errors (keep emailing me about those, please!)
|
120 |
+
* Removed second comment in source output.
|
121 |
+
* Fixed version number output in source.
|
122 |
+
|
123 |
+
= 4.0.9 =
|
124 |
+
|
125 |
+
* Code enhancements:
|
126 |
+
* Updated Shopp integration to also work with the upcoming Shopp 1.1 and higher.
|
127 |
+
* Switched from [split](http://php.net/split) to [explode](http://php.net/explode), as split has been deprecated in PHP 5.3+.
|
128 |
+
* New features:
|
129 |
+
* A new debug mode has been added, using the new [ga_debug.js](http://analytics.blogspot.com/2010/08/new-tools-to-debug-your-tracking-code.html). Along with this you can now enable Firebug Lite, so you can easily see the output from the debug script in each browser. Admins only, of course.
|
130 |
+
* A list of modules has been added to the right sidebar, to allow easy navigation within the settings page.
|
131 |
+
|
132 |
+
= 4.0.8 =
|
133 |
+
* Reverted double quote change from 4.0.7 because it was causing bigger issues.
|
134 |
+
|
135 |
+
= 4.0.7 =
|
136 |
+
* Bugs fixed in this release:
|
137 |
+
* Changed access level from "edit_users" to "manage_options" so super-admins in an multi site environment would be able to access.
|
138 |
+
* Not a real bug but a fix nonetheless: UA ID is now trimmed on output, so spaces accidently entered in the settings screen won't prevent tracking.
|
139 |
+
* Changed double quotes in link tracking output to single quotes to resolve incompatibilities with several plugins.
|
140 |
+
|
141 |
+
= 4.0.6 =
|
142 |
+
* Bugs fixed in this release:
|
143 |
+
* Sanitizing relative URL's could go wrong on some blogs installed in subdirectories.
|
144 |
+
* Comment form tracking only worked for posts, not for pages, and would sometimes cause other issues. Patch by [Milan Dinić](http://blog.milandinic.com/).
|
145 |
+
* Settings page: now correctly hiding internal links to track as outbound block when outbound link tracking is disabled.
|
146 |
+
* Code sanitization:
|
147 |
+
* Hardcoded the [scope for custom variables](http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._setCustomVar) to prevent that from possibly going wrong.
|
148 |
+
* Improved method of determining whether current user should be tracked or not.
|
149 |
+
* Added plugin version number in script branding comment, and moved branding comment to within CDATA section to assist in debugging, even when people use W3TC or another form of code minification.
|
150 |
+
* Documentation fixes:
|
151 |
+
* Updated custom variable order in settings panel to reflect order of tracking. You can now determine their index key by counting down, first checked box is index 1, second 2, etc.
|
152 |
+
* Ignored users dropdown now correctly reflects that ignoring subcribers and up means ignoring ALL logged in users.
|
153 |
+
|
154 |
+
= 4.0.5 =
|
155 |
+
* New features in this release:
|
156 |
+
* Added a simple check to see if the UA code, when entered manually, matches a basic pattern of UA-1234567-12.
|
157 |
+
* Added integration with [W3 Total Cache](http://wordpress.org/extend/plugins/w3-total-cache/) and [WP Super Cache](http://wordpress.org/extend/plugins/wp-super-cache/). The page cache is now automatically cleared after updating settings. Caching is recommended for all WordPress users, as faster page loads improve tracking reliability and W3 Total Cache is our recommended caching plugin.
|
158 |
+
* Added the option to enter a manual location for ga.js, allowing you to host it locally should you wish to.
|
159 |
+
* Bugs fixed:
|
160 |
+
* Fixed implementation of _anonymizeIp, it now correctly anonymizes IP's by setting [_gat._anonymizeIp](http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gat.html#_gat._anonymizeIp).
|
161 |
+
* Increased request timeout time for Google Analytics authentication from 10 to 20 seconds, for slow hosts (if this fixes it for you, your hosting is probably not really good, consider another WordPress host).
|
162 |
+
* Documentation fixes:
|
163 |
+
* Added a note about profiles with the same UA code to the Analytics Profile selection.
|
164 |
+
* The profile selection dropdown now shows the UA code after the profile name too.
|
165 |
+
* Updated the [screenshots](http://wordpress.org/extend/plugins/google-analytics-for-wordpress/screenshots/) and the [FAQ](http://wordpress.org/extend/plugins/google-analytics-for-wordpress/faq/) for this plugin.
|
166 |
+
|
167 |
+
= 4.0.4 =
|
168 |
+
* Fix for stupid boolean mistake in 4.0.3.
|
169 |
+
|
170 |
+
= 4.0.3 =
|
171 |
+
* New features in this release:
|
172 |
+
* Added versioning to the options array, to allow for easy addition of options.
|
173 |
+
* Added an option to enable comment form tracking (as this loads jQuery), defaults to on.
|
174 |
+
* Bugs fixed:
|
175 |
+
* If you upgraded from before 4.0 to 4.0.2 you might have an empty value for ignore_userlevel in some edge cases, this is now fixed.
|
176 |
+
* Custom search engines were loaded after trackPageview, this was wrong as shown [by these docs](http://code.google.com/intl/sr/apis/analytics/docs/tracking/asyncMigrationExamples.html#SearchEngines), now fixed.
|
177 |
+
|
178 |
+
= 4.0.2 =
|
179 |
+
* Old settings from versions below 4.0 are now properly sanitized and inherited (slaps forehead about simplicity of fix).
|
180 |
+
* New features in this release:
|
181 |
+
* Link sanitization added: relative links will be rewritten to absolute, so /out/ becomes http://example.com/out/ and is tracked properly.
|
182 |
+
* Added a feature to track and label internal links as outbound clicks, for instance /out/ links.
|
183 |
+
* Added tracking for mailto: links.
|
184 |
+
* Added a filter for text-widgets, all links in those widgets are now tagged too.
|
185 |
+
* Added support for [_anonymizeIp](http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gat.html#_gat._anonymizeIp).
|
186 |
+
* Bugs fixed in this release:
|
187 |
+
* Made sure all content filters don't run when the current user is ignored because of his user level.
|
188 |
+
|
189 |
+
= 4.0.1 =
|
190 |
+
* Fix for when you have only 1 site in a specific Analytics profile.
|
191 |
+
|
192 |
+
= 4.0 =
|
193 |
+
* NOTE WHEN UPGRADING: you'll have to reconfigure the plugin so it can fully support all the new features!
|
194 |
+
* Complete rewrite of the codebase
|
195 |
+
* Switched to the new asynchronous event tracking model
|
196 |
+
* Switched link tracking to an event tracking model, because of this change removed 5 settings from the settings panel that were no longer needed
|
197 |
+
* Implemented custom variable tracking to track:
|
198 |
+
* On the session level: whether the user is logged in or not.
|
199 |
+
* On the page level: the current posts's author, category, tags, year of publication and post type.
|
200 |
+
* Added Google Analytics API integration, so you can easily select a site to track.
|
201 |
+
* E-Commerce integration, tracking transactions, support for WP E-Commerce and Shopp.
|
202 |
+
* Much much more: check out [the release post](http://yoast.com/google-analytics-wordpress-v4/).
|
203 |
+
|
204 |
+
= 3.2.3 =
|
205 |
+
* Added 0 result search tracking inspired by [Justin Cutroni's post](http://www.epikone.com/blog/2009/09/08/tracking-ero-result-searches-in-google-analytics/).
|
206 |
+
|
207 |
+
= 3.2.2 =
|
208 |
+
* Fix to the hashtag redirect so it actually works in all cases.
|
209 |
+
|
210 |
+
= 3.2.1 =
|
211 |
+
* Slight change to RSS URL tagging, now setting campaign to post name, and behaving better when not using rewritten URL's.
|
212 |
+
* Two patches by [Lee Willis](http://www.leewillis.co.uk):
|
213 |
+
* Made some changes so the entire plugin works fine with .co.uk, .co.za etc domains.
|
214 |
+
* Made sure internal blogroll links aren't tagged as external clicks.
|
215 |
+
|
216 |
+
= 3.2 =
|
217 |
+
* Added option to add tracking to add tracking to login / register pages, so you can track new signups (under Advanced settings).
|
218 |
+
* Added beta option to track Google image search as a search engine, needs more testing to make sure it works.
|
219 |
+
* Fixed a bug in the extra search engine tracking implementation.
|
220 |
+
* Removed redundant "More Info" section from readme.txt.
|
221 |
+
|
222 |
+
= 3.1.1 =
|
223 |
+
* Stupid typo that caused warnings.
|
224 |
+
|
225 |
+
= 3.1 =
|
226 |
+
* Added 404 tracking as described [here](http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&answer=86927).
|
227 |
+
* Optimized the tracking script, if extra search engine tracking is disabled it'll be a lot smaller now.
|
228 |
+
* Various code optimizations to prevent PHP notices and removal of redundant code.
|
229 |
+
|
230 |
+
= 3.0.1 =
|
231 |
+
* Removed no longer needed code to add config page that caused PHP warnings.
|
232 |
+
|
233 |
+
= 3.0 =
|
234 |
+
* Major backend overhaul, using new Yoast backend class.
|
235 |
+
* Added ability to automatically redirect non hashtagged campaign URLs to hashtagged campaign URL's when setAllowAnchor is set to true (if you don't get it, forget about it, you might need it but don't need to worry)
|
236 |
+
|
237 |
+
= 2.9.5 =
|
238 |
+
* Fixed a bug with the included RSS, which came up when multiple Yoast plugins were installed.
|
239 |
+
|
240 |
+
= 2.9.4 =
|
241 |
+
* Changed to the new Changelog design.
|
242 |
+
* Removed pre 2.6 compatibility code, plugin now requires WP 2.6 or higher.
|
243 |
+
* Small changes to the admin screen.
|
244 |
+
|
245 |
+
= 2.9.3 =
|
246 |
+
* Added a new option for RSS link tagging, which allows you to tag your RSS feed links with RSS campaign variables. When you've set campaign variables to use # instead of ?, this will adhere to that setting too. Thanks to [Timan Rebel](http://rebelic.nl/) for the idea and code.
|
247 |
+
|
248 |
+
= 2.9.2: =
|
249 |
+
* Added a check to see whether the wp_footer() call is in footer.php.
|
250 |
+
* Added a message to the source when tracking code is left out because user is logged in as admin.
|
251 |
+
* Added option to segment logged in users.
|
252 |
+
* Added try - catch to script lines like in new Google Analytics scripts.
|
253 |
+
* Fixed bug in warning when no UA code is entered.
|
254 |
+
* Prevent link tracking when admin is logged in and admin tracking is disabled.
|
255 |
+
* Now prevents parsing of non http and https link.
|
256 |
+
|
257 |
+
= 2.9 =
|
258 |
+
* Re arranged admin panel to have "standard" and "advanced" settings.
|
259 |
+
* Added domain tracking.
|
260 |
+
* Added fix for double onclick parameter, as suggested [here](http://wordpress.org/support/topic/241757).
|
261 |
+
|
262 |
+
= 2.8 =
|
263 |
+
* Added the option to add setAllowAnchor to the tracking code, allowing you to track campaigns with # instead of ?.
|
264 |
+
|
265 |
+
= 2.7 =
|
266 |
+
* Added option to select either header of footer position.
|
267 |
+
* Added new AdSense integration options.
|
268 |
+
* Removed now unneeded adsense tracking script.
|
269 |
+
|
270 |
+
= 2.6.6=
|
271 |
+
* Fixed settings link.
|
272 |
+
|
273 |
+
= 2.6.5 =
|
274 |
+
* added Ozh admin menu icon and settings link.
|
275 |
+
|
276 |
+
= 2.6.4 =
|
277 |
+
* Fixes for 2.7.
|
278 |
+
|
279 |
+
= 2.6.3 =
|
280 |
+
* Fixed bug that didn't allow saving of outbound clicks from comments string.
|
281 |
+
|
282 |
+
= 2.6 =
|
283 |
+
* Fixed incompatibility with WP 2.6.
|
284 |
+
|
285 |
+
= 2.5.4 =
|
286 |
+
* Fixed an issue with pluginpath being used globally.
|
287 |
+
* Changed links to [new domain](http://yoast.com/).
|
288 |
+
|
289 |
+
= 2.2 =
|
290 |
+
* Switched to the new tracking code.
|
291 |
+
|
292 |
+
= 2.1 =
|
293 |
+
* Made sure tracking was disabled on preview pages.
|
294 |
+
|
295 |
+
= 2.0 =
|
296 |
+
* Added AdSense tracking.
|
297 |
+
|
298 |
+
= 1.5 =
|
299 |
+
* Added option to enable admin tracking, off by default.
|
300 |
+
|
301 |
+
== Frequently Asked Questions ==
|
302 |
+
|
303 |
+
= Can I run this plugin together with another Google Analytics plugin? =
|
304 |
+
|
305 |
+
No. You can not. It will break tracking.
|
306 |
+
|
307 |
+
= Another profile than the one I selected is showing as selected? =
|
308 |
+
|
309 |
+
You probably have multiple profiles for the same website, that share the same UA-code. If so, it doesn't matter which of the profiles is shown as selected, tracking will be correct.
|
310 |
+
|
311 |
+
= I've just installed the new tracking and Google Analytics says it's not receiving data yet? =
|
312 |
+
|
313 |
+
Give it a couple of hours, usually it'll be fixed. It can take up to 24 hours to appear though.
|
314 |
+
|
315 |
+
= Google Analytics says it's receiving data, but I don't see any stats yet? =
|
316 |
+
|
317 |
+
This can take up to 24 hours after the installation of the new tracking code.
|
318 |
+
|
319 |
+
= Why is the tracking code loaded in the head section of the site? =
|
320 |
+
|
321 |
+
Because that's where it belongs. It makes the page load faster (yes, faster, due to the asynchronous method of loading the script) and tracking more reliable. If you must place it in the footer anyway, switch to manual mode and check out the docs for [manual placement of the Google Analytics code](http://yoast.com/wordpress/google-analytics/manual-placement/).
|
322 |
+
|
323 |
+
== Screenshots ==
|
324 |
+
|
325 |
+
1. Screenshot of the basic settings panel for this plugin.
|
326 |
+
2. Screenshot of the custom variable settings panel.
|
327 |
+
3. Screenshot of the link tracking panel.
|
328 |
+
4. Screenshot of the advanced settings panel.
|
329 |
+
5. Screenshot of the debugging mode in action.
|
330 |
+
|
331 |
+
== Upgrade Notice ==
|
332 |
+
|
333 |
+
= 4.0.11 =
|
334 |
+
|
335 |
+
You can now properly disable the comment form tracking, and the charset attribute on script tags is gone so you can validate as HTML5 too.
|
wp-gdata/OAuth.php
ADDED
@@ -0,0 +1,895 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// vim: foldmethod=marker
|
3 |
+
|
4 |
+
/* Generic exception class
|
5 |
+
*/
|
6 |
+
class OAuthException extends Exception {
|
7 |
+
// pass
|
8 |
+
}
|
9 |
+
|
10 |
+
class OAuthConsumer {
|
11 |
+
public $key;
|
12 |
+
public $secret;
|
13 |
+
|
14 |
+
function __construct($key, $secret, $callback_url=NULL) {
|
15 |
+
$this->key = $key;
|
16 |
+
$this->secret = $secret;
|
17 |
+
$this->callback_url = $callback_url;
|
18 |
+
}
|
19 |
+
|
20 |
+
function __toString() {
|
21 |
+
return "OAuthConsumer[key=$this->key,secret=$this->secret]";
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
class OAuthToken {
|
26 |
+
// access tokens and request tokens
|
27 |
+
public $key;
|
28 |
+
public $secret;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* key = the token
|
32 |
+
* secret = the token secret
|
33 |
+
*/
|
34 |
+
function __construct($key, $secret) {
|
35 |
+
$this->key = $key;
|
36 |
+
$this->secret = $secret;
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* generates the basic string serialization of a token that a server
|
41 |
+
* would respond to request_token and access_token calls with
|
42 |
+
*/
|
43 |
+
function to_string() {
|
44 |
+
return "oauth_token=" .
|
45 |
+
OAuthUtil::urlencode_rfc3986($this->key) .
|
46 |
+
"&oauth_token_secret=" .
|
47 |
+
OAuthUtil::urlencode_rfc3986($this->secret);
|
48 |
+
}
|
49 |
+
|
50 |
+
function __toString() {
|
51 |
+
return $this->to_string();
|
52 |
+
}
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* A class for implementing a Signature Method
|
57 |
+
* See section 9 ("Signing Requests") in the spec
|
58 |
+
*/
|
59 |
+
abstract class OAuthSignatureMethod {
|
60 |
+
/**
|
61 |
+
* Needs to return the name of the Signature Method (ie HMAC-SHA1)
|
62 |
+
* @return string
|
63 |
+
*/
|
64 |
+
abstract public function get_name();
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Build up the signature
|
68 |
+
* NOTE: The output of this function MUST NOT be urlencoded.
|
69 |
+
* the encoding is handled in OAuthRequest when the final
|
70 |
+
* request is serialized
|
71 |
+
* @param OAuthRequest $request
|
72 |
+
* @param OAuthConsumer $consumer
|
73 |
+
* @param OAuthToken $token
|
74 |
+
* @return string
|
75 |
+
*/
|
76 |
+
abstract public function build_signature($request, $consumer, $token);
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Verifies that a given signature is correct
|
80 |
+
* @param OAuthRequest $request
|
81 |
+
* @param OAuthConsumer $consumer
|
82 |
+
* @param OAuthToken $token
|
83 |
+
* @param string $signature
|
84 |
+
* @return bool
|
85 |
+
*/
|
86 |
+
public function check_signature($request, $consumer, $token, $signature) {
|
87 |
+
$built = $this->build_signature($request, $consumer, $token);
|
88 |
+
|
89 |
+
// Check for zero length, although unlikely here
|
90 |
+
if (strlen($built) == 0 || strlen($signature) == 0) {
|
91 |
+
return false;
|
92 |
+
}
|
93 |
+
|
94 |
+
if (strlen($built) != strlen($signature)) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
// Avoid a timing leak with a (hopefully) time insensitive compare
|
99 |
+
$result = 0;
|
100 |
+
for ($i = 0; $i < strlen($signature); $i++) {
|
101 |
+
$result |= ord($built{$i}) ^ ord($signature{$i});
|
102 |
+
}
|
103 |
+
|
104 |
+
return $result == 0;
|
105 |
+
}
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104]
|
110 |
+
* where the Signature Base String is the text and the key is the concatenated values (each first
|
111 |
+
* encoded per Parameter Encoding) of the Consumer Secret and Token Secret, separated by an '&'
|
112 |
+
* character (ASCII code 38) even if empty.
|
113 |
+
* - Chapter 9.2 ("HMAC-SHA1")
|
114 |
+
*/
|
115 |
+
class OAuthSignatureMethod_HMAC_SHA1 extends OAuthSignatureMethod {
|
116 |
+
function get_name() {
|
117 |
+
return "HMAC-SHA1";
|
118 |
+
}
|
119 |
+
|
120 |
+
public function build_signature($request, $consumer, $token) {
|
121 |
+
$base_string = $request->get_signature_base_string();
|
122 |
+
$request->base_string = $base_string;
|
123 |
+
|
124 |
+
$key_parts = array(
|
125 |
+
$consumer->secret,
|
126 |
+
($token) ? $token->secret : ""
|
127 |
+
);
|
128 |
+
|
129 |
+
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
130 |
+
$key = implode('&', $key_parts);
|
131 |
+
|
132 |
+
return base64_encode(hash_hmac('sha1', $base_string, $key, true));
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* The PLAINTEXT method does not provide any security protection and SHOULD only be used
|
138 |
+
* over a secure channel such as HTTPS. It does not use the Signature Base String.
|
139 |
+
* - Chapter 9.4 ("PLAINTEXT")
|
140 |
+
*/
|
141 |
+
class OAuthSignatureMethod_PLAINTEXT extends OAuthSignatureMethod {
|
142 |
+
public function get_name() {
|
143 |
+
return "PLAINTEXT";
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* oauth_signature is set to the concatenated encoded values of the Consumer Secret and
|
148 |
+
* Token Secret, separated by a '&' character (ASCII code 38), even if either secret is
|
149 |
+
* empty. The result MUST be encoded again.
|
150 |
+
* - Chapter 9.4.1 ("Generating Signatures")
|
151 |
+
*
|
152 |
+
* Please note that the second encoding MUST NOT happen in the SignatureMethod, as
|
153 |
+
* OAuthRequest handles this!
|
154 |
+
*/
|
155 |
+
public function build_signature($request, $consumer, $token) {
|
156 |
+
$key_parts = array(
|
157 |
+
$consumer->secret,
|
158 |
+
($token) ? $token->secret : ""
|
159 |
+
);
|
160 |
+
|
161 |
+
$key_parts = OAuthUtil::urlencode_rfc3986($key_parts);
|
162 |
+
$key = implode('&', $key_parts);
|
163 |
+
$request->base_string = $key;
|
164 |
+
|
165 |
+
return $key;
|
166 |
+
}
|
167 |
+
}
|
168 |
+
|
169 |
+
/**
|
170 |
+
* The RSA-SHA1 signature method uses the RSASSA-PKCS1-v1_5 signature algorithm as defined in
|
171 |
+
* [RFC3447] section 8.2 (more simply known as PKCS#1), using SHA-1 as the hash function for
|
172 |
+
* EMSA-PKCS1-v1_5. It is assumed that the Consumer has provided its RSA public key in a
|
173 |
+
* verified way to the Service Provider, in a manner which is beyond the scope of this
|
174 |
+
* specification.
|
175 |
+
* - Chapter 9.3 ("RSA-SHA1")
|
176 |
+
*/
|
177 |
+
abstract class OAuthSignatureMethod_RSA_SHA1 extends OAuthSignatureMethod {
|
178 |
+
public function get_name() {
|
179 |
+
return "RSA-SHA1";
|
180 |
+
}
|
181 |
+
|
182 |
+
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
183 |
+
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
184 |
+
// (2) fetch via http using a url provided by the requester
|
185 |
+
// (3) some sort of specific discovery code based on request
|
186 |
+
//
|
187 |
+
// Either way should return a string representation of the certificate
|
188 |
+
protected abstract function fetch_public_cert(&$request);
|
189 |
+
|
190 |
+
// Up to the SP to implement this lookup of keys. Possible ideas are:
|
191 |
+
// (1) do a lookup in a table of trusted certs keyed off of consumer
|
192 |
+
//
|
193 |
+
// Either way should return a string representation of the certificate
|
194 |
+
protected abstract function fetch_private_cert(&$request);
|
195 |
+
|
196 |
+
public function build_signature($request, $consumer, $token) {
|
197 |
+
$base_string = $request->get_signature_base_string();
|
198 |
+
$request->base_string = $base_string;
|
199 |
+
|
200 |
+
// Fetch the private key cert based on the request
|
201 |
+
$cert = $this->fetch_private_cert($request);
|
202 |
+
|
203 |
+
// Pull the private key ID from the certificate
|
204 |
+
$privatekeyid = openssl_get_privatekey($cert);
|
205 |
+
|
206 |
+
// Sign using the key
|
207 |
+
$ok = openssl_sign($base_string, $signature, $privatekeyid);
|
208 |
+
|
209 |
+
// Release the key resource
|
210 |
+
openssl_free_key($privatekeyid);
|
211 |
+
|
212 |
+
return base64_encode($signature);
|
213 |
+
}
|
214 |
+
|
215 |
+
public function check_signature($request, $consumer, $token, $signature) {
|
216 |
+
$decoded_sig = base64_decode($signature);
|
217 |
+
|
218 |
+
$base_string = $request->get_signature_base_string();
|
219 |
+
|
220 |
+
// Fetch the public key cert based on the request
|
221 |
+
$cert = $this->fetch_public_cert($request);
|
222 |
+
|
223 |
+
// Pull the public key ID from the certificate
|
224 |
+
$publickeyid = openssl_get_publickey($cert);
|
225 |
+
|
226 |
+
// Check the computed signature against the one passed in the query
|
227 |
+
$ok = openssl_verify($base_string, $decoded_sig, $publickeyid);
|
228 |
+
|
229 |
+
// Release the key resource
|
230 |
+
openssl_free_key($publickeyid);
|
231 |
+
|
232 |
+
return $ok == 1;
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
class OAuthRequest {
|
237 |
+
protected $parameters;
|
238 |
+
protected $http_method;
|
239 |
+
protected $http_url;
|
240 |
+
// for debug purposes
|
241 |
+
public $base_string;
|
242 |
+
public static $version = '1.0';
|
243 |
+
public static $POST_INPUT = 'php://input';
|
244 |
+
|
245 |
+
function __construct($http_method, $http_url, $parameters=NULL) {
|
246 |
+
$parameters = ($parameters) ? $parameters : array();
|
247 |
+
$parameters = array_merge( OAuthUtil::parse_parameters(parse_url($http_url, PHP_URL_QUERY)), $parameters);
|
248 |
+
$this->parameters = $parameters;
|
249 |
+
$this->http_method = $http_method;
|
250 |
+
$this->http_url = $http_url;
|
251 |
+
}
|
252 |
+
|
253 |
+
|
254 |
+
/**
|
255 |
+
* attempt to build up a request from what was passed to the server
|
256 |
+
*/
|
257 |
+
public static function from_request($http_method=NULL, $http_url=NULL, $parameters=NULL) {
|
258 |
+
$scheme = (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != "on")
|
259 |
+
? 'http'
|
260 |
+
: 'https';
|
261 |
+
$http_url = ($http_url) ? $http_url : $scheme .
|
262 |
+
'://' . $_SERVER['SERVER_NAME'] .
|
263 |
+
':' .
|
264 |
+
$_SERVER['SERVER_PORT'] .
|
265 |
+
$_SERVER['REQUEST_URI'];
|
266 |
+
$http_method = ($http_method) ? $http_method : $_SERVER['REQUEST_METHOD'];
|
267 |
+
|
268 |
+
// We weren't handed any parameters, so let's find the ones relevant to
|
269 |
+
// this request.
|
270 |
+
// If you run XML-RPC or similar you should use this to provide your own
|
271 |
+
// parsed parameter-list
|
272 |
+
if (!$parameters) {
|
273 |
+
// Find request headers
|
274 |
+
$request_headers = OAuthUtil::get_headers();
|
275 |
+
|
276 |
+
// Parse the query-string to find GET parameters
|
277 |
+
$parameters = OAuthUtil::parse_parameters($_SERVER['QUERY_STRING']);
|
278 |
+
|
279 |
+
// It's a POST request of the proper content-type, so parse POST
|
280 |
+
// parameters and add those overriding any duplicates from GET
|
281 |
+
if ($http_method == "POST"
|
282 |
+
&& isset($request_headers['Content-Type'])
|
283 |
+
&& strstr($request_headers['Content-Type'],
|
284 |
+
'application/x-www-form-urlencoded')
|
285 |
+
) {
|
286 |
+
$post_data = OAuthUtil::parse_parameters(
|
287 |
+
file_get_contents(self::$POST_INPUT)
|
288 |
+
);
|
289 |
+
$parameters = array_merge($parameters, $post_data);
|
290 |
+
}
|
291 |
+
|
292 |
+
// We have a Authorization-header with OAuth data. Parse the header
|
293 |
+
// and add those overriding any duplicates from GET or POST
|
294 |
+
if (isset($request_headers['Authorization']) && substr($request_headers['Authorization'], 0, 6) == 'OAuth ') {
|
295 |
+
$header_parameters = OAuthUtil::split_header(
|
296 |
+
$request_headers['Authorization']
|
297 |
+
);
|
298 |
+
$parameters = array_merge($parameters, $header_parameters);
|
299 |
+
}
|
300 |
+
|
301 |
+
}
|
302 |
+
|
303 |
+
return new OAuthRequest($http_method, $http_url, $parameters);
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* pretty much a helper function to set up the request
|
308 |
+
*/
|
309 |
+
public static function from_consumer_and_token($consumer, $token, $http_method, $http_url, $parameters=NULL) {
|
310 |
+
$parameters = ($parameters) ? $parameters : array();
|
311 |
+
$defaults = array("oauth_version" => OAuthRequest::$version,
|
312 |
+
"oauth_nonce" => OAuthRequest::generate_nonce(),
|
313 |
+
"oauth_timestamp" => OAuthRequest::generate_timestamp(),
|
314 |
+
"oauth_consumer_key" => $consumer->key);
|
315 |
+
if ($token)
|
316 |
+
$defaults['oauth_token'] = $token->key;
|
317 |
+
|
318 |
+
$parameters = array_merge($defaults, $parameters);
|
319 |
+
|
320 |
+
return new OAuthRequest($http_method, $http_url, $parameters);
|
321 |
+
}
|
322 |
+
|
323 |
+
public function set_parameter($name, $value, $allow_duplicates = true) {
|
324 |
+
if ($allow_duplicates && isset($this->parameters[$name])) {
|
325 |
+
// We have already added parameter(s) with this name, so add to the list
|
326 |
+
if (is_scalar($this->parameters[$name])) {
|
327 |
+
// This is the first duplicate, so transform scalar (string)
|
328 |
+
// into an array so we can add the duplicates
|
329 |
+
$this->parameters[$name] = array($this->parameters[$name]);
|
330 |
+
}
|
331 |
+
|
332 |
+
$this->parameters[$name][] = $value;
|
333 |
+
} else {
|
334 |
+
$this->parameters[$name] = $value;
|
335 |
+
}
|
336 |
+
}
|
337 |
+
|
338 |
+
public function get_parameter($name) {
|
339 |
+
return isset($this->parameters[$name]) ? $this->parameters[$name] : null;
|
340 |
+
}
|
341 |
+
|
342 |
+
public function get_parameters() {
|
343 |
+
return $this->parameters;
|
344 |
+
}
|
345 |
+
|
346 |
+
public function unset_parameter($name) {
|
347 |
+
unset($this->parameters[$name]);
|
348 |
+
}
|
349 |
+
|
350 |
+
/**
|
351 |
+
* The request parameters, sorted and concatenated into a normalized string.
|
352 |
+
* @return string
|
353 |
+
*/
|
354 |
+
public function get_signable_parameters() {
|
355 |
+
// Grab all parameters
|
356 |
+
$params = $this->parameters;
|
357 |
+
|
358 |
+
// Remove oauth_signature if present
|
359 |
+
// Ref: Spec: 9.1.1 ("The oauth_signature parameter MUST be excluded.")
|
360 |
+
if (isset($params['oauth_signature'])) {
|
361 |
+
unset($params['oauth_signature']);
|
362 |
+
}
|
363 |
+
|
364 |
+
return OAuthUtil::build_http_query($params);
|
365 |
+
}
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Returns the base string of this request
|
369 |
+
*
|
370 |
+
* The base string defined as the method, the url
|
371 |
+
* and the parameters (normalized), each urlencoded
|
372 |
+
* and the concated with &.
|
373 |
+
*/
|
374 |
+
public function get_signature_base_string() {
|
375 |
+
$parts = array(
|
376 |
+
$this->get_normalized_http_method(),
|
377 |
+
$this->get_normalized_http_url(),
|
378 |
+
$this->get_signable_parameters()
|
379 |
+
);
|
380 |
+
|
381 |
+
$parts = OAuthUtil::urlencode_rfc3986($parts);
|
382 |
+
|
383 |
+
return implode('&', $parts);
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* just uppercases the http method
|
388 |
+
*/
|
389 |
+
public function get_normalized_http_method() {
|
390 |
+
return strtoupper($this->http_method);
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* parses the url and rebuilds it to be
|
395 |
+
* scheme://host/path
|
396 |
+
*/
|
397 |
+
public function get_normalized_http_url() {
|
398 |
+
$parts = parse_url($this->http_url);
|
399 |
+
|
400 |
+
$scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
|
401 |
+
$port = (isset($parts['port'])) ? $parts['port'] : (($scheme == 'https') ? '443' : '80');
|
402 |
+
$host = (isset($parts['host'])) ? strtolower($parts['host']) : '';
|
403 |
+
$path = (isset($parts['path'])) ? $parts['path'] : '';
|
404 |
+
|
405 |
+
if (($scheme == 'https' && $port != '443')
|
406 |
+
|| ($scheme == 'http' && $port != '80')) {
|
407 |
+
$host = "$host:$port";
|
408 |
+
}
|
409 |
+
return "$scheme://$host$path";
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
* builds a url usable for a GET request
|
414 |
+
*/
|
415 |
+
public function to_url() {
|
416 |
+
$post_data = $this->to_postdata();
|
417 |
+
$out = $this->get_normalized_http_url();
|
418 |
+
if ($post_data) {
|
419 |
+
$out .= '?'.$post_data;
|
420 |
+
}
|
421 |
+
return $out;
|
422 |
+
}
|
423 |
+
|
424 |
+
/**
|
425 |
+
* builds the data one would send in a POST request
|
426 |
+
*/
|
427 |
+
public function to_postdata() {
|
428 |
+
return OAuthUtil::build_http_query($this->parameters);
|
429 |
+
}
|
430 |
+
|
431 |
+
/**
|
432 |
+
* builds the Authorization: header
|
433 |
+
*/
|
434 |
+
public function to_header($realm=null) {
|
435 |
+
$first = true;
|
436 |
+
if($realm) {
|
437 |
+
$out = 'Authorization: OAuth realm="' . OAuthUtil::urlencode_rfc3986($realm) . '"';
|
438 |
+
$first = false;
|
439 |
+
} else
|
440 |
+
$out = 'Authorization: OAuth';
|
441 |
+
|
442 |
+
$total = array();
|
443 |
+
foreach ($this->parameters as $k => $v) {
|
444 |
+
if (substr($k, 0, 5) != "oauth") continue;
|
445 |
+
if (is_array($v)) {
|
446 |
+
throw new OAuthException('Arrays not supported in headers');
|
447 |
+
}
|
448 |
+
$out .= ($first) ? ' ' : ',';
|
449 |
+
$out .= OAuthUtil::urlencode_rfc3986($k) .
|
450 |
+
'="' .
|
451 |
+
OAuthUtil::urlencode_rfc3986($v) .
|
452 |
+
'"';
|
453 |
+
$first = false;
|
454 |
+
}
|
455 |
+
return $out;
|
456 |
+
}
|
457 |
+
|
458 |
+
public function __toString() {
|
459 |
+
return $this->to_url();
|
460 |
+
}
|
461 |
+
|
462 |
+
|
463 |
+
public function sign_request($signature_method, $consumer, $token) {
|
464 |
+
$this->set_parameter(
|
465 |
+
"oauth_signature_method",
|
466 |
+
$signature_method->get_name(),
|
467 |
+
false
|
468 |
+
);
|
469 |
+
$signature = $this->build_signature($signature_method, $consumer, $token);
|
470 |
+
$this->set_parameter("oauth_signature", $signature, false);
|
471 |
+
}
|
472 |
+
|
473 |
+
public function build_signature($signature_method, $consumer, $token) {
|
474 |
+
$signature = $signature_method->build_signature($this, $consumer, $token);
|
475 |
+
return $signature;
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* util function: current timestamp
|
480 |
+
*/
|
481 |
+
private static function generate_timestamp() {
|
482 |
+
return time();
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* util function: current nonce
|
487 |
+
*/
|
488 |
+
private static function generate_nonce() {
|
489 |
+
$mt = microtime();
|
490 |
+
$rand = mt_rand();
|
491 |
+
|
492 |
+
return md5($mt . $rand); // md5s look nicer than numbers
|
493 |
+
}
|
494 |
+
}
|
495 |
+
|
496 |
+
class OAuthServer {
|
497 |
+
protected $timestamp_threshold = 300; // in seconds, five minutes
|
498 |
+
protected $version = '1.0'; // hi blaine
|
499 |
+
protected $signature_methods = array();
|
500 |
+
|
501 |
+
protected $data_store;
|
502 |
+
|
503 |
+
function __construct($data_store) {
|
504 |
+
$this->data_store = $data_store;
|
505 |
+
}
|
506 |
+
|
507 |
+
public function add_signature_method($signature_method) {
|
508 |
+
$this->signature_methods[$signature_method->get_name()] =
|
509 |
+
$signature_method;
|
510 |
+
}
|
511 |
+
|
512 |
+
// high level functions
|
513 |
+
|
514 |
+
/**
|
515 |
+
* process a request_token request
|
516 |
+
* returns the request token on success
|
517 |
+
*/
|
518 |
+
public function fetch_request_token(&$request) {
|
519 |
+
$this->get_version($request);
|
520 |
+
|
521 |
+
$consumer = $this->get_consumer($request);
|
522 |
+
|
523 |
+
// no token required for the initial token request
|
524 |
+
$token = NULL;
|
525 |
+
|
526 |
+
$this->check_signature($request, $consumer, $token);
|
527 |
+
|
528 |
+
// Rev A change
|
529 |
+
$callback = $request->get_parameter('oauth_callback');
|
530 |
+
$new_token = $this->data_store->new_request_token($consumer, $callback);
|
531 |
+
|
532 |
+
return $new_token;
|
533 |
+
}
|
534 |
+
|
535 |
+
/**
|
536 |
+
* process an access_token request
|
537 |
+
* returns the access token on success
|
538 |
+
*/
|
539 |
+
public function fetch_access_token(&$request) {
|
540 |
+
$this->get_version($request);
|
541 |
+
|
542 |
+
$consumer = $this->get_consumer($request);
|
543 |
+
|
544 |
+
// requires authorized request token
|
545 |
+
$token = $this->get_token($request, $consumer, "request");
|
546 |
+
|
547 |
+
$this->check_signature($request, $consumer, $token);
|
548 |
+
|
549 |
+
// Rev A change
|
550 |
+
$verifier = $request->get_parameter('oauth_verifier');
|
551 |
+
$new_token = $this->data_store->new_access_token($token, $consumer, $verifier);
|
552 |
+
|
553 |
+
return $new_token;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* verify an api call, checks all the parameters
|
558 |
+
*/
|
559 |
+
public function verify_request(&$request) {
|
560 |
+
$this->get_version($request);
|
561 |
+
$consumer = $this->get_consumer($request);
|
562 |
+
$token = $this->get_token($request, $consumer, "access");
|
563 |
+
$this->check_signature($request, $consumer, $token);
|
564 |
+
return array($consumer, $token);
|
565 |
+
}
|
566 |
+
|
567 |
+
// Internals from here
|
568 |
+
/**
|
569 |
+
* version 1
|
570 |
+
*/
|
571 |
+
private function get_version(&$request) {
|
572 |
+
$version = $request->get_parameter("oauth_version");
|
573 |
+
if (!$version) {
|
574 |
+
// Service Providers MUST assume the protocol version to be 1.0 if this parameter is not present.
|
575 |
+
// Chapter 7.0 ("Accessing Protected Ressources")
|
576 |
+
$version = '1.0';
|
577 |
+
}
|
578 |
+
if ($version !== $this->version) {
|
579 |
+
throw new OAuthException("OAuth version '$version' not supported");
|
580 |
+
}
|
581 |
+
return $version;
|
582 |
+
}
|
583 |
+
|
584 |
+
/**
|
585 |
+
* figure out the signature with some defaults
|
586 |
+
*/
|
587 |
+
private function get_signature_method($request) {
|
588 |
+
$signature_method = $request instanceof OAuthRequest
|
589 |
+
? $request->get_parameter("oauth_signature_method")
|
590 |
+
: NULL;
|
591 |
+
|
592 |
+
if (!$signature_method) {
|
593 |
+
// According to chapter 7 ("Accessing Protected Ressources") the signature-method
|
594 |
+
// parameter is required, and we can't just fallback to PLAINTEXT
|
595 |
+
throw new OAuthException('No signature method parameter. This parameter is required');
|
596 |
+
}
|
597 |
+
|
598 |
+
if (!in_array($signature_method,
|
599 |
+
array_keys($this->signature_methods))) {
|
600 |
+
throw new OAuthException(
|
601 |
+
"Signature method '$signature_method' not supported " .
|
602 |
+
"try one of the following: " .
|
603 |
+
implode(", ", array_keys($this->signature_methods))
|
604 |
+
);
|
605 |
+
}
|
606 |
+
return $this->signature_methods[$signature_method];
|
607 |
+
}
|
608 |
+
|
609 |
+
/**
|
610 |
+
* try to find the consumer for the provided request's consumer key
|
611 |
+
*/
|
612 |
+
private function get_consumer($request) {
|
613 |
+
$consumer_key = $request instanceof OAuthRequest
|
614 |
+
? $request->get_parameter("oauth_consumer_key")
|
615 |
+
: NULL;
|
616 |
+
|
617 |
+
if (!$consumer_key) {
|
618 |
+
throw new OAuthException("Invalid consumer key");
|
619 |
+
}
|
620 |
+
|
621 |
+
$consumer = $this->data_store->lookup_consumer($consumer_key);
|
622 |
+
if (!$consumer) {
|
623 |
+
throw new OAuthException("Invalid consumer");
|
624 |
+
}
|
625 |
+
|
626 |
+
return $consumer;
|
627 |
+
}
|
628 |
+
|
629 |
+
/**
|
630 |
+
* try to find the token for the provided request's token key
|
631 |
+
*/
|
632 |
+
private function get_token($request, $consumer, $token_type="access") {
|
633 |
+
$token_field = $request instanceof OAuthRequest
|
634 |
+
? $request->get_parameter('oauth_token')
|
635 |
+
: NULL;
|
636 |
+
|
637 |
+
$token = $this->data_store->lookup_token(
|
638 |
+
$consumer, $token_type, $token_field
|
639 |
+
);
|
640 |
+
if (!$token) {
|
641 |
+
throw new OAuthException("Invalid $token_type token: $token_field");
|
642 |
+
}
|
643 |
+
return $token;
|
644 |
+
}
|
645 |
+
|
646 |
+
/**
|
647 |
+
* all-in-one function to check the signature on a request
|
648 |
+
* should guess the signature method appropriately
|
649 |
+
*/
|
650 |
+
private function check_signature($request, $consumer, $token) {
|
651 |
+
// this should probably be in a different method
|
652 |
+
$timestamp = $request instanceof OAuthRequest
|
653 |
+
? $request->get_parameter('oauth_timestamp')
|
654 |
+
: NULL;
|
655 |
+
$nonce = $request instanceof OAuthRequest
|
656 |
+
? $request->get_parameter('oauth_nonce')
|
657 |
+
: NULL;
|
658 |
+
|
659 |
+
$this->check_timestamp($timestamp);
|
660 |
+
$this->check_nonce($consumer, $token, $nonce, $timestamp);
|
661 |
+
|
662 |
+
$signature_method = $this->get_signature_method($request);
|
663 |
+
|
664 |
+
$signature = $request->get_parameter('oauth_signature');
|
665 |
+
$valid_sig = $signature_method->check_signature(
|
666 |
+
$request,
|
667 |
+
$consumer,
|
668 |
+
$token,
|
669 |
+
$signature
|
670 |
+
);
|
671 |
+
|
672 |
+
if (!$valid_sig) {
|
673 |
+
throw new OAuthException("Invalid signature");
|
674 |
+
}
|
675 |
+
}
|
676 |
+
|
677 |
+
/**
|
678 |
+
* check that the timestamp is new enough
|
679 |
+
*/
|
680 |
+
private function check_timestamp($timestamp) {
|
681 |
+
if( ! $timestamp )
|
682 |
+
throw new OAuthException(
|
683 |
+
'Missing timestamp parameter. The parameter is required'
|
684 |
+
);
|
685 |
+
|
686 |
+
// verify that timestamp is recentish
|
687 |
+
$now = time();
|
688 |
+
if (abs($now - $timestamp) > $this->timestamp_threshold) {
|
689 |
+
throw new OAuthException(
|
690 |
+
"Expired timestamp, yours $timestamp, ours $now"
|
691 |
+
);
|
692 |
+
}
|
693 |
+
}
|
694 |
+
|
695 |
+
/**
|
696 |
+
* check that the nonce is not repeated
|
697 |
+
*/
|
698 |
+
private function check_nonce($consumer, $token, $nonce, $timestamp) {
|
699 |
+
if( ! $nonce )
|
700 |
+
throw new OAuthException(
|
701 |
+
'Missing nonce parameter. The parameter is required'
|
702 |
+
);
|
703 |
+
|
704 |
+
// verify that the nonce is uniqueish
|
705 |
+
$found = $this->data_store->lookup_nonce(
|
706 |
+
$consumer,
|
707 |
+
$token,
|
708 |
+
$nonce,
|
709 |
+
$timestamp
|
710 |
+
);
|
711 |
+
if ($found) {
|
712 |
+
throw new OAuthException("Nonce already used: $nonce");
|
713 |
+
}
|
714 |
+
}
|
715 |
+
|
716 |
+
}
|
717 |
+
|
718 |
+
class OAuthDataStore {
|
719 |
+
function lookup_consumer($consumer_key) {
|
720 |
+
// implement me
|
721 |
+
}
|
722 |
+
|
723 |
+
function lookup_token($consumer, $token_type, $token) {
|
724 |
+
// implement me
|
725 |
+
}
|
726 |
+
|
727 |
+
function lookup_nonce($consumer, $token, $nonce, $timestamp) {
|
728 |
+
// implement me
|
729 |
+
}
|
730 |
+
|
731 |
+
function new_request_token($consumer, $callback = null) {
|
732 |
+
// return a new token attached to this consumer
|
733 |
+
}
|
734 |
+
|
735 |
+
function new_access_token($token, $consumer, $verifier = null) {
|
736 |
+
// return a new access token attached to this consumer
|
737 |
+
// for the user associated with this token if the request token
|
738 |
+
// is authorized
|
739 |
+
// should also invalidate the request token
|
740 |
+
}
|
741 |
+
|
742 |
+
}
|
743 |
+
|
744 |
+
class OAuthUtil {
|
745 |
+
public static function urlencode_rfc3986($input) {
|
746 |
+
if (is_array($input)) {
|
747 |
+
return array_map(array('OAuthUtil', 'urlencode_rfc3986'), $input);
|
748 |
+
} else if (is_scalar($input)) {
|
749 |
+
return str_replace(
|
750 |
+
'+',
|
751 |
+
' ',
|
752 |
+
str_replace('%7E', '~', rawurlencode($input))
|
753 |
+
);
|
754 |
+
} else {
|
755 |
+
return '';
|
756 |
+
}
|
757 |
+
}
|
758 |
+
|
759 |
+
|
760 |
+
// This decode function isn't taking into consideration the above
|
761 |
+
// modifications to the encoding process. However, this method doesn't
|
762 |
+
// seem to be used anywhere so leaving it as is.
|
763 |
+
public static function urldecode_rfc3986($string) {
|
764 |
+
return urldecode($string);
|
765 |
+
}
|
766 |
+
|
767 |
+
// Utility function for turning the Authorization: header into
|
768 |
+
// parameters, has to do some unescaping
|
769 |
+
// Can filter out any non-oauth parameters if needed (default behaviour)
|
770 |
+
// May 28th, 2010 - method updated to tjerk.meesters for a speed improvement.
|
771 |
+
// see http://code.google.com/p/oauth/issues/detail?id=163
|
772 |
+
public static function split_header($header, $only_allow_oauth_parameters = true) {
|
773 |
+
$params = array();
|
774 |
+
if (preg_match_all('/('.($only_allow_oauth_parameters ? 'oauth_' : '').'[a-z_-]*)=(:?"([^"]*)"|([^,]*))/', $header, $matches)) {
|
775 |
+
foreach ($matches[1] as $i => $h) {
|
776 |
+
$params[$h] = OAuthUtil::urldecode_rfc3986(empty($matches[3][$i]) ? $matches[4][$i] : $matches[3][$i]);
|
777 |
+
}
|
778 |
+
if (isset($params['realm'])) {
|
779 |
+
unset($params['realm']);
|
780 |
+
}
|
781 |
+
}
|
782 |
+
return $params;
|
783 |
+
}
|
784 |
+
|
785 |
+
// helper to try to sort out headers for people who aren't running apache
|
786 |
+
public static function get_headers() {
|
787 |
+
if (function_exists('apache_request_headers')) {
|
788 |
+
// we need this to get the actual Authorization: header
|
789 |
+
// because apache tends to tell us it doesn't exist
|
790 |
+
$headers = apache_request_headers();
|
791 |
+
|
792 |
+
// sanitize the output of apache_request_headers because
|
793 |
+
// we always want the keys to be Cased-Like-This and arh()
|
794 |
+
// returns the headers in the same case as they are in the
|
795 |
+
// request
|
796 |
+
$out = array();
|
797 |
+
foreach ($headers AS $key => $value) {
|
798 |
+
$key = str_replace(
|
799 |
+
" ",
|
800 |
+
"-",
|
801 |
+
ucwords(strtolower(str_replace("-", " ", $key)))
|
802 |
+
);
|
803 |
+
$out[$key] = $value;
|
804 |
+
}
|
805 |
+
} else {
|
806 |
+
// otherwise we don't have apache and are just going to have to hope
|
807 |
+
// that $_SERVER actually contains what we need
|
808 |
+
$out = array();
|
809 |
+
if( isset($_SERVER['CONTENT_TYPE']) )
|
810 |
+
$out['Content-Type'] = $_SERVER['CONTENT_TYPE'];
|
811 |
+
if( isset($_ENV['CONTENT_TYPE']) )
|
812 |
+
$out['Content-Type'] = $_ENV['CONTENT_TYPE'];
|
813 |
+
|
814 |
+
foreach ($_SERVER as $key => $value) {
|
815 |
+
if (substr($key, 0, 5) == "HTTP_") {
|
816 |
+
// this is chaos, basically it is just there to capitalize the first
|
817 |
+
// letter of every word that is not an initial HTTP and strip HTTP
|
818 |
+
// code from przemek
|
819 |
+
$key = str_replace(
|
820 |
+
" ",
|
821 |
+
"-",
|
822 |
+
ucwords(strtolower(str_replace("_", " ", substr($key, 5))))
|
823 |
+
);
|
824 |
+
$out[$key] = $value;
|
825 |
+
}
|
826 |
+
}
|
827 |
+
}
|
828 |
+
return $out;
|
829 |
+
}
|
830 |
+
|
831 |
+
// This function takes a input like a=b&a=c&d=e and returns the parsed
|
832 |
+
// parameters like this
|
833 |
+
// array('a' => array('b','c'), 'd' => 'e')
|
834 |
+
public static function parse_parameters( $input ) {
|
835 |
+
if (!isset($input) || !$input) return array();
|
836 |
+
|
837 |
+
$pairs = explode('&', $input);
|
838 |
+
|
839 |
+
$parsed_parameters = array();
|
840 |
+
foreach ($pairs as $pair) {
|
841 |
+
$split = explode('=', $pair, 2);
|
842 |
+
$parameter = OAuthUtil::urldecode_rfc3986($split[0]);
|
843 |
+
$value = isset($split[1]) ? OAuthUtil::urldecode_rfc3986($split[1]) : '';
|
844 |
+
|
845 |
+
if (isset($parsed_parameters[$parameter])) {
|
846 |
+
// We have already recieved parameter(s) with this name, so add to the list
|
847 |
+
// of parameters with this name
|
848 |
+
|
849 |
+
if (is_scalar($parsed_parameters[$parameter])) {
|
850 |
+
// This is the first duplicate, so transform scalar (string) into an array
|
851 |
+
// so we can add the duplicates
|
852 |
+
$parsed_parameters[$parameter] = array($parsed_parameters[$parameter]);
|
853 |
+
}
|
854 |
+
|
855 |
+
$parsed_parameters[$parameter][] = $value;
|
856 |
+
} else {
|
857 |
+
$parsed_parameters[$parameter] = $value;
|
858 |
+
}
|
859 |
+
}
|
860 |
+
return $parsed_parameters;
|
861 |
+
}
|
862 |
+
|
863 |
+
public static function build_http_query($params) {
|
864 |
+
if (!$params) return '';
|
865 |
+
|
866 |
+
// Urlencode both keys and values
|
867 |
+
$keys = OAuthUtil::urlencode_rfc3986(array_keys($params));
|
868 |
+
$values = OAuthUtil::urlencode_rfc3986(array_values($params));
|
869 |
+
$params = array_combine($keys, $values);
|
870 |
+
|
871 |
+
// Parameters are sorted by name, using lexicographical byte value ordering.
|
872 |
+
// Ref: Spec: 9.1.1 (1)
|
873 |
+
uksort($params, 'strcmp');
|
874 |
+
|
875 |
+
$pairs = array();
|
876 |
+
foreach ($params as $parameter => $value) {
|
877 |
+
if (is_array($value)) {
|
878 |
+
// If two or more parameters share the same name, they are sorted by their value
|
879 |
+
// Ref: Spec: 9.1.1 (1)
|
880 |
+
// June 12th, 2010 - changed to sort because of issue 164 by hidetaka
|
881 |
+
sort($value, SORT_STRING);
|
882 |
+
foreach ($value as $duplicate_value) {
|
883 |
+
$pairs[] = $parameter . '=' . $duplicate_value;
|
884 |
+
}
|
885 |
+
} else {
|
886 |
+
$pairs[] = $parameter . '=' . $value;
|
887 |
+
}
|
888 |
+
}
|
889 |
+
// For each parameter, the name is separated from the corresponding value by an '=' character (ASCII code 61)
|
890 |
+
// Each name-value pair is separated by an '&' character (ASCII code 38)
|
891 |
+
return implode('&', $pairs);
|
892 |
+
}
|
893 |
+
}
|
894 |
+
|
895 |
+
?>
|
wp-gdata/wp-gdata.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* WP_GData - WordPress Google Data API Library
|
4 |
+
*
|
5 |
+
* @author Pete Mall
|
6 |
+
*/
|
7 |
+
|
8 |
+
// Load the OAuth library.
|
9 |
+
if ( ! class_exists( 'OAuthConsumer' ) )
|
10 |
+
require( 'OAuth.php' );
|
11 |
+
|
12 |
+
class WP_GData {
|
13 |
+
/* Contains the last HTTP status code returned. */
|
14 |
+
public $http_code;
|
15 |
+
|
16 |
+
const request_token_url = 'https://www.google.com/accounts/OAuthGetRequestToken';
|
17 |
+
const authorize_url = 'https://www.google.com/accounts/OAuthAuthorizeToken';
|
18 |
+
const access_token_url = 'https://www.google.com/accounts/OAuthGetAccessToken';
|
19 |
+
|
20 |
+
function __construct( $parameters = array(), $oauth_token = null, $oauth_token_secret = null ) {
|
21 |
+
$this->parameters = $parameters;
|
22 |
+
$this->signature_method = new OAuthSignatureMethod_HMAC_SHA1();
|
23 |
+
$this->consumer = new OAuthConsumer( 'anonymous', 'anonymous' );
|
24 |
+
|
25 |
+
if ( !empty( $oauth_token ) && !empty( $oauth_token_secret ) )
|
26 |
+
$this->token = new OAuthConsumer( $oauth_token, $oauth_token_secret );
|
27 |
+
else
|
28 |
+
$this->token = null;
|
29 |
+
}
|
30 |
+
|
31 |
+
function get_request_token( $oauth_callback = null ) {
|
32 |
+
$parameters = $this->parameters;
|
33 |
+
if ( !empty( $oauth_callback ) )
|
34 |
+
$parameters['oauth_callback'] = $oauth_callback;
|
35 |
+
|
36 |
+
$request = $this->oauth_request( self::request_token_url, 'GET', $parameters );
|
37 |
+
$token = OAuthUtil::parse_parameters( wp_remote_retrieve_body( $request ) );
|
38 |
+
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
39 |
+
return $token;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Format and sign an OAuth / API request
|
44 |
+
*/
|
45 |
+
private function oauth_request( $url, $method, $parameters ) {
|
46 |
+
$request = OAuthRequest::from_consumer_and_token( $this->consumer, $this->token, $method, $url, $parameters );
|
47 |
+
$request->sign_request( $this->signature_method, $this->consumer, $this->token );
|
48 |
+
|
49 |
+
if ( 'GET' == $method )
|
50 |
+
return wp_remote_get( $request->to_url() );
|
51 |
+
else
|
52 |
+
return wp_remote_post( $request->to_url(), $request->to_postdata() );
|
53 |
+
}
|
54 |
+
|
55 |
+
function get_authorize_url( $token ) {
|
56 |
+
if ( is_array( $token ) )
|
57 |
+
$token = $token['oauth_token'];
|
58 |
+
|
59 |
+
return self::authorize_url . "?oauth_token={$token}";
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Exchange request token and secret for an access token and
|
64 |
+
* secret, to sign API calls.
|
65 |
+
*
|
66 |
+
* @returns array( 'oauth_token' => 'the-access-token',
|
67 |
+
* 'oauth_token_secret' => 'the-access-secret' )
|
68 |
+
*/
|
69 |
+
function get_access_token( $oauth_verifier = '' ) {
|
70 |
+
$parameters = array();
|
71 |
+
if ( !empty( $oauth_verifier ) )
|
72 |
+
$parameters['oauth_verifier'] = $oauth_verifier;
|
73 |
+
|
74 |
+
$request = $this->oauth_request( self::access_token_url, 'GET', $parameters );
|
75 |
+
$token = OAuthUtil::parse_parameters( wp_remote_retrieve_body( $request ) );
|
76 |
+
$this->token = new OAuthConsumer( $token['oauth_token'], $token['oauth_token_secret'] );
|
77 |
+
return $token;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* GET wrapper for oAuthRequest.
|
82 |
+
*/
|
83 |
+
public function get( $url, $parameters = array() ) {
|
84 |
+
return $this->oauth_request( $url, 'GET', $parameters );
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* POST wrapper for oAuthRequest.
|
89 |
+
*/
|
90 |
+
public function post( $url, $parameters = array() ) {
|
91 |
+
$defaults = array(
|
92 |
+
'method' => 'POST',
|
93 |
+
'timeout' => 30,
|
94 |
+
'redirection' => 5,
|
95 |
+
'httpversion' => '1.0',
|
96 |
+
'blocking' => true,
|
97 |
+
'body' => array(),
|
98 |
+
'headers' => array(),
|
99 |
+
'cookies' => array()
|
100 |
+
);
|
101 |
+
$parameters = array_merge( $defaults, $parameters );
|
102 |
+
|
103 |
+
return $this->oauth_request( $url, 'POST', $parameters );
|
104 |
+
}
|
105 |
+
}
|
yst_plugin_tools.css
CHANGED
@@ -1,81 +1,96 @@
|
|
1 |
-
td.yst_desc {
|
2 |
-
font-weight: normal;
|
3 |
-
font-size: 12px;
|
4 |
-
line-height: 12px;
|
5 |
-
color:#777;
|
6 |
-
}
|
7 |
-
|
8 |
-
tr.yst_row {
|
9 |
-
padding: 5px 0 0 0;
|
10 |
-
margin: 5px 0 0 0;
|
11 |
-
}
|
12 |
-
tr.yst_row.even {
|
13 |
-
background-color: #f6f6f6;
|
14 |
-
}
|
15 |
-
|
16 |
-
div.inside ul {
|
17 |
-
margin-left: 20px;
|
18 |
-
}
|
19 |
-
|
20 |
-
div.inside ul li {
|
21 |
-
list-style: square;
|
22 |
-
line-height:16px;
|
23 |
-
}
|
24 |
-
|
25 |
-
div.inside a, div.inside a.rsswidget {
|
26 |
-
font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
|
27 |
-
text-decoration: none;
|
28 |
-
}
|
29 |
-
div.inside a:hover, div.inside a.rsswidget:hover {
|
30 |
-
text-decoration: underline;
|
31 |
-
}
|
32 |
-
div.inside ul li.rss {
|
33 |
-
list-style-image: url(images/rss.png);
|
34 |
-
}
|
35 |
-
|
36 |
-
div.inside ul li.email {
|
37 |
-
list-style-image: url(images/email_sub.png);
|
38 |
-
}
|
39 |
-
|
40 |
-
div.inside ul li.yoast {
|
41 |
-
list-style-image: url(images/yoast-16x16.png);
|
42 |
-
}
|
43 |
-
|
44 |
-
.text, .select {
|
45 |
-
width: 250px;
|
46 |
-
}
|
47 |
-
|
48 |
-
.postbox p {
|
49 |
-
text-align:left;
|
50 |
-
margin: 0 10px 10px 10px;
|
51 |
-
font-size: 13px;
|
52 |
-
line-height: 150%;
|
53 |
-
}
|
54 |
-
|
55 |
-
.postbox pre {
|
56 |
-
margin: 5px 10px;
|
57 |
-
padding:4px;
|
58 |
-
background: lightyellow;
|
59 |
-
}
|
60 |
-
|
61 |
-
.side .postbox p, .side .postbox a, .side .postbox a.rsswidget {
|
62 |
-
font-size: 11px;
|
63 |
-
}
|
64 |
|
65 |
-
div.inside
|
66 |
-
|
67 |
}
|
68 |
|
69 |
-
.
|
70 |
-
|
71 |
}
|
72 |
|
73 |
-
.
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
-
strong.red {
|
78 |
-
color: green;
|
79 |
-
font-weight: bold;
|
80 |
-
font-size: 105%;
|
81 |
-
}
|
1 |
+
td.yst_desc {
|
2 |
+
font-weight: normal;
|
3 |
+
font-size: 12px;
|
4 |
+
line-height: 12px;
|
5 |
+
color:#777;
|
6 |
+
}
|
7 |
+
|
8 |
+
tr.yst_row {
|
9 |
+
padding: 5px 0 0 0;
|
10 |
+
margin: 5px 0 0 0;
|
11 |
+
}
|
12 |
+
tr.yst_row.even {
|
13 |
+
background-color: #f6f6f6;
|
14 |
+
}
|
15 |
+
|
16 |
+
div.inside ul {
|
17 |
+
margin-left: 20px;
|
18 |
+
}
|
19 |
+
|
20 |
+
div.inside ul li {
|
21 |
+
list-style: square;
|
22 |
+
line-height:16px;
|
23 |
+
}
|
24 |
+
|
25 |
+
div.inside a, div.inside a.rsswidget {
|
26 |
+
font-family: 'Lucida Grande', Verdana, Arial, 'Bitstream Vera Sans', sans-serif;
|
27 |
+
text-decoration: none;
|
28 |
+
}
|
29 |
+
div.inside a:hover, div.inside a.rsswidget:hover {
|
30 |
+
text-decoration: underline;
|
31 |
+
}
|
32 |
+
div.inside ul li.rss {
|
33 |
+
list-style-image: url(images/rss.png);
|
34 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
+
div.inside ul li.twitter {
|
37 |
+
list-style-image: url(images/twitter-icon.png);
|
38 |
}
|
39 |
|
40 |
+
div.inside ul li.facebook {
|
41 |
+
list-style-image: url(images/facebook-icon.png);
|
42 |
}
|
43 |
|
44 |
+
div.inside ul li.googleplus {
|
45 |
+
list-style-image: url(images/google-plus-icon.png);
|
46 |
+
}
|
47 |
+
|
48 |
+
div.inside ul li.email {
|
49 |
+
list-style-image: url(images/email_sub.png);
|
50 |
+
}
|
51 |
+
|
52 |
+
div.inside ul li.yoast {
|
53 |
+
list-style-image: url(images/yoast-16x16.png);
|
54 |
+
}
|
55 |
+
|
56 |
+
.text, .select {
|
57 |
+
width: 250px;
|
58 |
+
}
|
59 |
+
|
60 |
+
.postbox p {
|
61 |
+
text-align:left;
|
62 |
+
margin: 0 10px 10px 10px;
|
63 |
+
font-size: 13px;
|
64 |
+
line-height: 150%;
|
65 |
+
}
|
66 |
+
|
67 |
+
.postbox pre {
|
68 |
+
margin: 5px 10px;
|
69 |
+
padding:4px;
|
70 |
+
background: lightyellow;
|
71 |
+
}
|
72 |
+
|
73 |
+
.side .postbox p, .side .postbox a, .side .postbox a.rsswidget {
|
74 |
+
font-size: 11px;
|
75 |
+
}
|
76 |
+
|
77 |
+
div.inside .button:hover, div.inside .button-primary:hover {
|
78 |
+
text-decoration: none;
|
79 |
+
}
|
80 |
+
|
81 |
+
.button, .button-primary {
|
82 |
+
margin-top: 10px;
|
83 |
+
}
|
84 |
+
|
85 |
+
.postbox#donate {
|
86 |
+
border-color: green;
|
87 |
+
border-width: 2px;
|
88 |
+
}
|
89 |
+
strong.red {
|
90 |
+
color: green;
|
91 |
+
font-weight: bold;
|
92 |
+
font-size: 105%;
|
93 |
+
}
|
94 |
+
.postbox {
|
95 |
+
margin: 0 10px 10px 0;
|
96 |
}
|
|
|
|
|
|
|
|
|
|
yst_plugin_tools.php
CHANGED
@@ -1,257 +1,267 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Backend Class for use in all Yoast plugins
|
5 |
-
* Version 0.2
|
6 |
-
*/
|
7 |
-
|
8 |
-
if (!class_exists('Yoast_GA_Plugin_Admin')) {
|
9 |
-
class Yoast_GA_Plugin_Admin {
|
10 |
-
|
11 |
-
var $
|
12 |
-
var $
|
13 |
-
var $
|
14 |
-
var $
|
15 |
-
var $
|
16 |
-
var $
|
17 |
-
var $
|
18 |
-
var $
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
function
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
$
|
139 |
-
if (
|
140 |
-
$
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
$content .= '
|
146 |
-
if (
|
147 |
-
$content .= '<
|
148 |
-
|
149 |
-
|
150 |
-
$
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
$
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
if (
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
echo '
|
239 |
-
echo '<
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
257 |
?>
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Backend Class for use in all Yoast plugins
|
5 |
+
* Version 0.2
|
6 |
+
*/
|
7 |
+
|
8 |
+
if (!class_exists('Yoast_GA_Plugin_Admin')) {
|
9 |
+
class Yoast_GA_Plugin_Admin {
|
10 |
+
|
11 |
+
var $hook = '';
|
12 |
+
var $filename = '';
|
13 |
+
var $longname = '';
|
14 |
+
var $shortname = '';
|
15 |
+
var $ozhicon = '';
|
16 |
+
var $optionname = '';
|
17 |
+
var $homepage = '';
|
18 |
+
var $accesslvl = 'edit_users';
|
19 |
+
|
20 |
+
function Yoast_GA_Plugin_Admin() {
|
21 |
+
add_action( 'admin_menu', array(&$this, 'register_settings_page') );
|
22 |
+
add_filter( 'plugin_action_links', array(&$this, 'add_action_link'), 10, 2 );
|
23 |
+
add_filter( 'ozh_adminmenu_icon', array(&$this, 'add_ozh_adminmenu_icon' ) );
|
24 |
+
|
25 |
+
add_action('admin_print_scripts', array(&$this,'config_page_scripts'));
|
26 |
+
add_action('admin_print_styles', array(&$this,'config_page_styles'));
|
27 |
+
|
28 |
+
add_action('wp_dashboard_setup', array(&$this,'widget_setup'));
|
29 |
+
}
|
30 |
+
|
31 |
+
function add_ozh_adminmenu_icon( $hook ) {
|
32 |
+
if ($hook == $this->hook)
|
33 |
+
return plugin_dir_url( __FILE__ ).$this->ozhicon;
|
34 |
+
return $hook;
|
35 |
+
}
|
36 |
+
|
37 |
+
function config_page_styles() {
|
38 |
+
if (isset($_GET['page']) && $_GET['page'] == $this->hook) {
|
39 |
+
wp_enqueue_style('dashboard');
|
40 |
+
wp_enqueue_style('thickbox');
|
41 |
+
wp_enqueue_style('global');
|
42 |
+
wp_enqueue_style('wp-admin');
|
43 |
+
wp_enqueue_style('gawp-css', plugin_dir_url( __FILE__ ). 'yst_plugin_tools.css');
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
function register_settings_page() {
|
48 |
+
add_options_page($this->longname, $this->shortname, $this->accesslvl, $this->hook, array(&$this,'config_page'));
|
49 |
+
}
|
50 |
+
|
51 |
+
function plugin_options_url() {
|
52 |
+
return admin_url( 'options-general.php?page='.$this->hook );
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Add a link to the settings page to the plugins list
|
57 |
+
*/
|
58 |
+
function add_action_link( $links, $file ) {
|
59 |
+
static $this_plugin;
|
60 |
+
if( empty($this_plugin) ) $this_plugin = $this->filename;
|
61 |
+
if ( $file == $this_plugin ) {
|
62 |
+
$settings_link = '<a href="' . $this->plugin_options_url() . '">' . __('Settings', 'gawp_yoast') . '</a>';
|
63 |
+
array_unshift( $links, $settings_link );
|
64 |
+
}
|
65 |
+
return $links;
|
66 |
+
}
|
67 |
+
|
68 |
+
function config_page() {
|
69 |
+
|
70 |
+
}
|
71 |
+
|
72 |
+
function config_page_scripts() {
|
73 |
+
if (isset($_GET['page']) && $_GET['page'] == $this->hook) {
|
74 |
+
wp_enqueue_script('postbox');
|
75 |
+
wp_enqueue_script('dashboard');
|
76 |
+
wp_enqueue_script('thickbox');
|
77 |
+
wp_enqueue_script('media-upload');
|
78 |
+
}
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Create a Checkbox input field
|
83 |
+
*/
|
84 |
+
function checkbox($id) {
|
85 |
+
$options = get_option( $this->optionname );
|
86 |
+
return '<input type="checkbox" id="'.$id.'" name="'.$id.'"'. checked($options[$id],true,false).'/>';
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Create a Text input field
|
91 |
+
*/
|
92 |
+
function textinput($id) {
|
93 |
+
$options = get_option( $this->optionname );
|
94 |
+
return '<input class="text" type="text" id="'.$id.'" name="'.$id.'" size="30" value="'.$options[$id].'"/>';
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Create a dropdown field
|
99 |
+
*/
|
100 |
+
function select($id, $options, $multiple = false) {
|
101 |
+
$opt = get_option($this->optionname);
|
102 |
+
$output = '<select class="select" name="'.$id.'" id="'.$id.'">';
|
103 |
+
foreach ($options as $val => $name) {
|
104 |
+
$sel = '';
|
105 |
+
if ($opt[$id] == $val)
|
106 |
+
$sel = ' selected="selected"';
|
107 |
+
if ($name == '')
|
108 |
+
$name = $val;
|
109 |
+
$output .= '<option value="'.$val.'"'.$sel.'>'.$name.'</option>';
|
110 |
+
}
|
111 |
+
$output .= '</select>';
|
112 |
+
return $output;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Create a potbox widget
|
117 |
+
*/
|
118 |
+
function postbox($id, $title, $content) {
|
119 |
+
?>
|
120 |
+
<div id="<?php echo $id; ?>" class="postbox">
|
121 |
+
<div class="handlediv" title="Click to toggle"><br /></div>
|
122 |
+
<h3 class="hndle"><span><?php echo $title; ?></span></h3>
|
123 |
+
<div class="inside">
|
124 |
+
<?php echo $content; ?>
|
125 |
+
</div>
|
126 |
+
</div>
|
127 |
+
<?php
|
128 |
+
}
|
129 |
+
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Create a form table from an array of rows
|
133 |
+
*/
|
134 |
+
function form_table($rows) {
|
135 |
+
$content = '<table class="form-table">';
|
136 |
+
$i = 1;
|
137 |
+
foreach ($rows as $row) {
|
138 |
+
$class = '';
|
139 |
+
if ($i > 1) {
|
140 |
+
$class .= 'yst_row';
|
141 |
+
}
|
142 |
+
if ($i % 2 == 0) {
|
143 |
+
$class .= ' even';
|
144 |
+
}
|
145 |
+
$content .= '<tr id="'.$row['id'].'_row" class="'.$class.'"><th valign="top" scrope="row">';
|
146 |
+
if (isset($row['id']) && $row['id'] != '')
|
147 |
+
$content .= '<label for="'.$row['id'].'">'.$row['label'].':</label>';
|
148 |
+
else
|
149 |
+
$content .= $row['label'];
|
150 |
+
$content .= '</th><td valign="top">';
|
151 |
+
$content .= $row['content'];
|
152 |
+
$content .= '</td></tr>';
|
153 |
+
if ( isset($row['desc']) && !empty($row['desc']) ) {
|
154 |
+
$content .= '<tr class="'.$class.'"><td colspan="2" class="yst_desc"><small>'.$row['desc'].'</small></td></tr>';
|
155 |
+
}
|
156 |
+
|
157 |
+
$i++;
|
158 |
+
}
|
159 |
+
$content .= '</table>';
|
160 |
+
return $content;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Create a "plugin like" box.
|
165 |
+
*/
|
166 |
+
function plugin_like($hook = '') {
|
167 |
+
if (empty($hook)) {
|
168 |
+
$hook = $this->hook;
|
169 |
+
}
|
170 |
+
$content = '<p>'.__('Why not do any or all of the following:', 'gawp_yoast' ).'</p>';
|
171 |
+
$content .= '<ul>';
|
172 |
+
$content .= '<li><a href="'.$this->homepage.'">'.__('Link to it so other folks can find out about it.', 'gawp_yoast' ).'</a></li>';
|
173 |
+
$content .= '<li><a href="http://wordpress.org/extend/plugins/'.$hook.'/">'.__('Give it a 5 star rating on WordPress.org.', 'gawp_yoast' ).'</a></li>';
|
174 |
+
$content .= '<li><a href="http://wordpress.org/extend/plugins/'.$hook.'/">'.__('Let other people know that it works with your WordPress setup.', 'gawp_yoast' ).'</a></li>';
|
175 |
+
$content .= '</ul>';
|
176 |
+
$this->postbox($hook.'like', __( 'Like this plugin?', 'gawp_yoast' ), $content);
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Info box with link to the bug tracker.
|
181 |
+
*/
|
182 |
+
function plugin_support($hook = '') {
|
183 |
+
if (empty($hook)) {
|
184 |
+
$hook = $this->hook;
|
185 |
+
}
|
186 |
+
$content = '<p>'.sprintf( __( 'If you\'ve found a bug in this plugin, please submit it in the <a href="%s">Yoast Bug Tracker</a> with a clear description.', 'gawp_yoast' ), 'http://yoast.com/mantis/bug_report_page.php').'</p>';
|
187 |
+
$this->postbox($this->hook.'support', __('Found a bug?', 'gawp_yoast' ), $content);
|
188 |
+
}
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Box with latest news from Yoast.com
|
192 |
+
*/
|
193 |
+
function news() {
|
194 |
+
include_once(ABSPATH . WPINC . '/feed.php');
|
195 |
+
$rss = fetch_feed('http://feeds.feedburner.com/joostdevalk');
|
196 |
+
$rss_items = $rss->get_items( 0, $rss->get_item_quantity(5) );
|
197 |
+
$content = '<ul>';
|
198 |
+
if ( !$rss_items ) {
|
199 |
+
$content .= '<li class="yoast">'.__( 'No news items, feed might be broken...', 'gawp_yoast' ).'</li>';
|
200 |
+
} else {
|
201 |
+
foreach ( $rss_items as $item ) {
|
202 |
+
$content .= '<li class="yoast">';
|
203 |
+
$content .= '<a class="rsswidget" href="'.esc_url( $item->get_permalink(), $protocolls=null, 'display' ).'">'. esc_html($item->get_title()) .'</a> ';
|
204 |
+
$content .= '</li>';
|
205 |
+
}
|
206 |
+
}
|
207 |
+
$content .= '<li class="facebook"><a href="https://www.facebook.com/yoastcom">'.__( 'Like Yoast on Facebook', 'gawp_yoast' ).'</a></li>';
|
208 |
+
$content .= '<li class="twitter"><a href="http://twitter.com/yoast">'.__( 'Follow Yoast on Twitter', 'gawp_yoast' ).'</a></li>';
|
209 |
+
$content .= '<li class="googleplus"><a href="https://plus.google.com/115369062315673853712/posts">'.__( 'Circle Yoast on Google+', 'gawp_yoast' ).'</a></li>';
|
210 |
+
$content .= '<li class="rss"><a href="http://yoast.com/feed/">'.__( 'Subscribe with RSS', 'gawp_yoast' ).'</a></li>';
|
211 |
+
$content .= '<li class="email"><a href="http://yoast.com/email-blog-updates/">'.__( 'Subscribe by email', 'gawp_yoast' ).'</a></li>';
|
212 |
+
$content .= '</ul>';
|
213 |
+
$this->postbox('yoastlatest', __( 'Latest news from Yoast', 'gawp_yoast' ), $content);
|
214 |
+
}
|
215 |
+
|
216 |
+
function text_limit( $text, $limit, $finish = ' […]') {
|
217 |
+
if( strlen( $text ) > $limit ) {
|
218 |
+
$text = substr( $text, 0, $limit );
|
219 |
+
$text = substr( $text, 0, - ( strlen( strrchr( $text,' ') ) ) );
|
220 |
+
$text .= $finish;
|
221 |
+
}
|
222 |
+
return $text;
|
223 |
+
}
|
224 |
+
|
225 |
+
function db_widget() {
|
226 |
+
$options = get_option('yoastdbwidget');
|
227 |
+
if (isset($_POST['yoast_removedbwidget'])) {
|
228 |
+
$options['removedbwidget'] = true;
|
229 |
+
update_option('yoastdbwidget',$options);
|
230 |
+
}
|
231 |
+
if ($options['removedbwidget']) {
|
232 |
+
_e( "If you reload, this widget will be gone and never appear again, unless you decide to delete the database option 'yoastdbwidget'.", 'gawp_yoast' );
|
233 |
+
return;
|
234 |
+
}
|
235 |
+
require_once(ABSPATH.WPINC.'/rss.php');
|
236 |
+
if ( $rss = fetch_rss( 'http://yoast.com/feed/' ) ) {
|
237 |
+
echo '<div class="rss-widget">';
|
238 |
+
echo '<a href="http://yoast.com/" title="Go to Yoast.com"><img src="'.plugin_dir_url().'images/yoast-logo-rss.png" class="alignright" alt="Yoast"/></a>';
|
239 |
+
echo '<ul>';
|
240 |
+
$rss->items = array_slice( $rss->items, 0, 3 );
|
241 |
+
foreach ( (array) $rss->items as $item ) {
|
242 |
+
echo '<li>';
|
243 |
+
echo '<a class="rsswidget" href="'.clean_url( $item['link'], $protocolls=null, 'display' ).'">'. esc_html($item['title']) .'</a> ';
|
244 |
+
echo '<span class="rss-date">'. date('F j, Y', strtotime($item['pubdate'])) .'</span>';
|
245 |
+
echo '<div class="rssSummary">'. $this->text_limit($item['summary'],250) .'</div>';
|
246 |
+
echo '</li>';
|
247 |
+
}
|
248 |
+
echo '</ul>';
|
249 |
+
echo '<div style="border-top: 1px solid #ddd; padding-top: 10px; text-align:center;">';
|
250 |
+
echo '<a href="http://feeds2.feedburner.com/joostdevalk"><img src="'.get_bloginfo('wpurl').'/wp-includes/images/rss.png" alt=""/> Subscribe with RSS</a>';
|
251 |
+
echo ' ';
|
252 |
+
echo '<a href="http://yoast.com/email-blog-updates/"><img src="'.plugin_dir_url().'images/email_sub.png" alt=""/> '.__( 'Subscribe by email', 'gawp_yoast' ).'</a>';
|
253 |
+
echo '<form class="alignright" method="post"><input type="hidden" name="yoast_removedbwidget" value="true"/><input title="'.__( 'Remove this widget from all users dashboards', 'gawp_yoast' ).'" type="submit" value="X"/></form>';
|
254 |
+
echo '</div>';
|
255 |
+
echo '</div>';
|
256 |
+
}
|
257 |
+
}
|
258 |
+
|
259 |
+
function widget_setup() {
|
260 |
+
$options = get_option('yoastdbwidget');
|
261 |
+
if (!$options['removedbwidget'])
|
262 |
+
wp_add_dashboard_widget( 'yoast_db_widget' , __( 'The Latest news from Yoast', 'gawp_yoast' ) , array(&$this, 'db_widget'));
|
263 |
+
}
|
264 |
+
}
|
265 |
+
}
|
266 |
+
|
267 |
?>
|