Google Analytics for WordPress by MonsterInsights - Version 5.3

Version Description

Release Date: January 27th, 2015

  • Enhancements:

    • Added an option for entirely disabling the dashboards functionality. If a user disables the dashboard, the menu item gets moved downward since there no longer is a reason for putting it so far up.
    • Improved performance by making sure everything is autoloaded correctly and removing class inclusion checks everywhere.
    • Makes sure the menu items become translatable.
    • Added a button to save the GA authentication code as an alternative to hitting the return button.
    • Format the page views number in the hover label of dashboards.
    • Reduced the number of results retrieved from the Google Analytics API per call from 10,000 to 1,000. This is filterable through yst-ga-filter-api-limit.
  • Bugfixes:

    • When toggling checkbox the authentication token input was showing up.
    • Fixed internal links that were being tracked as outbound-article- (with trailing dash).
    • Makes sure re-authentication notice is only shown when authentication has actually failed.
    • Introduces a notice for when authentication isn't the problem but the plugin was somehow unable to fetch data from GA.
  • i18n:

    • Added translations for da_DK, es_MX, fr_FR, it_IT, nb_NO, pl_PL, pt_BR.
    • Updated translations for en_GB, he_IL, nl_NL, ru_RU.
Download this release

Release Info

Developer joostdevalk
Plugin Icon 128x128 Google Analytics for WordPress by MonsterInsights
Version 5.3
Comparing to
See all releases

Code changes from version 5.2.8 to 5.3

Files changed (48) hide show
  1. admin/class-admin-assets.php +70 -74
  2. admin/class-admin-form.php +250 -253
  3. admin/class-admin-menu.php +201 -138
  4. admin/class-admin.php +395 -416
  5. admin/class-google-analytics.php +304 -223
  6. admin/dashboards/class-admin-dashboards-api-options.php +68 -72
  7. admin/dashboards/class-admin-dashboards-collector.php +372 -358
  8. admin/dashboards/class-admin-dashboards-data.php +47 -41
  9. admin/dashboards/class-admin-dashboards-display.php +112 -116
  10. admin/dashboards/class-admin-dashboards.php +223 -185
  11. admin/dashboards/drivers/class-admin-dashboards-driver-generate.php +100 -104
  12. admin/dashboards/drivers/class-admin-dashboards-driver.php +63 -66
  13. admin/dashboards/drivers/class-admin-dashboards-graph-generate.php +126 -128
  14. admin/dashboards/drivers/class-admin-dashboards-graph.php +17 -20
  15. admin/dashboards/drivers/class-admin-dashboards-table-generate.php +52 -55
  16. admin/dashboards/drivers/class-admin-dashboards-table.php +17 -20
  17. admin/license-manager/composer.json +29 -0
  18. admin/pages/dashboard.php +1 -1
  19. admin/pages/extensions.php +2 -2
  20. admin/pages/settings.php +18 -15
  21. assets/js/yoast_ga_admin.js +20 -17
  22. assets/js/yoast_ga_admin.min.js +1 -1
  23. frontend/abstract-class-tracking.php +354 -304
  24. frontend/class-frontend.php +35 -39
  25. frontend/class-ga-js.php +138 -144
  26. frontend/class-universal.php +128 -135
  27. frontend/views/tracking-debug.php +2 -2
  28. frontend/views/tracking-ga-js.php +2 -2
  29. frontend/views/tracking-universal.php +2 -2
  30. frontend/views/tracking-usergroup.php +2 -2
  31. googleanalytics.php +4 -4
  32. includes/class-autoload.php +3 -1
  33. includes/class-options.php +238 -233
  34. includes/class-settings.php +56 -0
  35. includes/class-utils.php +31 -34
  36. languages/google-analytics-for-wordpress-da_DK.mo +0 -0
  37. languages/google-analytics-for-wordpress-en_GB.mo +0 -0
  38. languages/google-analytics-for-wordpress-es_MX.mo +0 -0
  39. languages/google-analytics-for-wordpress-fr_FR.mo +0 -0
  40. languages/google-analytics-for-wordpress-he_IL.mo +0 -0
  41. languages/google-analytics-for-wordpress-it_IT.mo +0 -0
  42. languages/google-analytics-for-wordpress-nb_NO.mo +0 -0
  43. languages/google-analytics-for-wordpress-nl_NL.mo +0 -0
  44. languages/google-analytics-for-wordpress-pl_PL.mo +0 -0
  45. languages/google-analytics-for-wordpress-pt_BR.mo +0 -0
  46. languages/google-analytics-for-wordpress-ru_RU.mo +0 -0
  47. languages/google-analytics-for-wordpress.pot +355 -117
  48. readme.txt +24 -2
admin/class-admin-assets.php CHANGED
@@ -3,101 +3,97 @@
3
  /**
4
  * This class is for the backend
5
  */
6
- if ( ! class_exists( 'Yoast_GA_Admin_Assets' ) ) {
7
 
8
- class Yoast_GA_Admin_Assets {
 
 
 
 
9
 
10
- /**
11
- * Add the scripts to the admin head
12
- */
13
- public static function enqueue_scripts() {
14
- wp_enqueue_script( 'yoast_focusable', self::get_asset_path( 'assets/dependencies/focusable/focus-element-overlay.min.js' ), array( 'jquery' ), false );
15
 
16
- wp_enqueue_script( 'yoast_ga_admin', self::get_asset_path( 'assets/js/yoast_ga_admin' ) . self::file_ext( '.js' ), array( 'jquery', 'yoast_focusable' ), GAWP_VERSION );
 
17
 
18
- // Enqueue the qtip js file
19
- wp_enqueue_script( 'jquery-qtip', self::get_asset_path( 'assets/dependencies/qtip/jquery.qtip.min.js' ) , array( 'jquery' ), '1.0.0-RC3', true );
 
20
 
21
- // Enqueue the chosen js file
22
- wp_enqueue_script( 'chosen_js', self::get_asset_path( 'assets/dependencies/chosen/chosen.jquery.min.js' ), array(), GAWP_VERSION, true );
23
- }
 
 
 
24
 
25
- /**
26
- * Add the styles in the admin head
27
- */
28
- public static function enqueue_styles() {
29
- wp_enqueue_style( 'yoast_ga_styles', self::get_asset_path( 'assets/css/yoast_ga_styles' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
30
- }
 
31
 
32
- /**
33
- * Enqueues the settings page specific styles
34
- */
35
- public static function enqueue_settings_styles() {
36
- // Enqueue the chosen css file
37
- wp_enqueue_style( 'chosen_css', self::get_asset_path( 'assets/dependencies/chosen/chosen' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
38
- }
39
 
40
- /**
41
- * Loading the assets for dashboard
42
- */
43
- public static function enqueue_dashboard_assets() {
44
 
45
- //
46
- wp_enqueue_script('ga-admin-dashboard', self::get_asset_path( 'assets/js/yoast_ga_admin_dashboard' ) . self::file_ext( '.js' ), array(), GAWP_VERSION );
47
- wp_enqueue_style('ga-admin-dashboard-css', self::get_asset_path( 'assets/css/yoast_ga_admin_dashboard' ). self::file_ext( '.css' ), array(), GAWP_VERSION ) ;
48
 
49
- // Enqueue the d3 js file
50
- wp_enqueue_script( 'd3_js', self::get_asset_path( 'assets/dependencies/rickshaw/d3.v3.min.js' ), array(), GAWP_VERSION, true );
51
 
52
- // Enqueue the ricksaw js file
53
- wp_enqueue_script( 'rickshaw_js', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.js' ), array(), GAWP_VERSION, true );
54
 
55
- // Enqueue the rickshaw css
56
- wp_enqueue_style( 'rickshaw_css', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.css' ), array(), GAWP_VERSION );
57
 
58
- // Enqueue the datatables js file
59
- wp_enqueue_script( 'datatables_js', self::get_asset_path( 'assets/dependencies/datatables/js/jquery.dataTables.min.js' ), array(), GAWP_VERSION, true );
60
 
61
- // Enqueue the datatables css
62
- wp_enqueue_style( 'datatables_css', self::get_asset_path( 'assets/dependencies/datatables/css/jquery.dataTables.min.css' ), array(), GAWP_VERSION );
63
 
64
- Yoast_GA_Dashboards::get_instance()->add_dashboard_js_translations();
 
 
 
 
 
 
 
 
 
 
 
65
  }
66
 
67
- /**
68
- * Getting the full path to given $asset
69
- *
70
- * @param string $asset
71
- *
72
- * @return string
73
- */
74
- private static function get_asset_path( $asset ) {
75
- static $plugin_directory;
76
-
77
- if ( $plugin_directory == null ) {
78
- $plugin_directory = plugin_dir_url( GAWP_FILE );
79
- }
80
-
81
- $return = $plugin_directory . $asset;
82
 
83
- return $return;
84
- }
85
 
86
- /**
87
- * Check whether we can include the minified version or not
88
- *
89
- * @param string $ext
90
- *
91
- * @return string
92
- */
93
- private static function file_ext( $ext ) {
94
- if ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) {
95
- $ext = '.min' . $ext;
96
- }
97
-
98
- return $ext;
99
  }
100
 
 
101
  }
102
 
103
  }
3
  /**
4
  * This class is for the backend
5
  */
6
+ class Yoast_GA_Admin_Assets {
7
 
8
+ /**
9
+ * Add the scripts to the admin head
10
+ */
11
+ public static function enqueue_scripts() {
12
+ wp_enqueue_script( 'yoast_focusable', self::get_asset_path( 'assets/dependencies/focusable/focus-element-overlay.min.js' ), array( 'jquery' ), false );
13
 
14
+ wp_enqueue_script( 'yoast_ga_admin', self::get_asset_path( 'assets/js/yoast_ga_admin' ) . self::file_ext( '.js' ), array( 'jquery', 'yoast_focusable' ), GAWP_VERSION );
 
 
 
 
15
 
16
+ // Enqueue the qtip js file
17
+ wp_enqueue_script( 'jquery-qtip', self::get_asset_path( 'assets/dependencies/qtip/jquery.qtip.min.js' ), array( 'jquery' ), '1.0.0-RC3', true );
18
 
19
+ // Enqueue the chosen js file
20
+ wp_enqueue_script( 'chosen_js', self::get_asset_path( 'assets/dependencies/chosen/chosen.jquery.min.js' ), array(), GAWP_VERSION, true );
21
+ }
22
 
23
+ /**
24
+ * Add the styles in the admin head
25
+ */
26
+ public static function enqueue_styles() {
27
+ wp_enqueue_style( 'yoast_ga_styles', self::get_asset_path( 'assets/css/yoast_ga_styles' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
28
+ }
29
 
30
+ /**
31
+ * Enqueues the settings page specific styles
32
+ */
33
+ public static function enqueue_settings_styles() {
34
+ // Enqueue the chosen css file
35
+ wp_enqueue_style( 'chosen_css', self::get_asset_path( 'assets/dependencies/chosen/chosen' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
36
+ }
37
 
38
+ /**
39
+ * Loading the assets for dashboard
40
+ */
41
+ public static function enqueue_dashboard_assets() {
 
 
 
42
 
43
+ //
44
+ wp_enqueue_script( 'ga-admin-dashboard', self::get_asset_path( 'assets/js/yoast_ga_admin_dashboard' ) . self::file_ext( '.js' ), array(), GAWP_VERSION );
45
+ wp_enqueue_style( 'ga-admin-dashboard-css', self::get_asset_path( 'assets/css/yoast_ga_admin_dashboard' ) . self::file_ext( '.css' ), array(), GAWP_VERSION );
 
46
 
47
+ // Enqueue the d3 js file
48
+ wp_enqueue_script( 'd3_js', self::get_asset_path( 'assets/dependencies/rickshaw/d3.v3.min.js' ), array(), GAWP_VERSION, true );
 
49
 
50
+ // Enqueue the ricksaw js file
51
+ wp_enqueue_script( 'rickshaw_js', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.js' ), array(), GAWP_VERSION, true );
52
 
53
+ // Enqueue the rickshaw css
54
+ wp_enqueue_style( 'rickshaw_css', self::get_asset_path( 'assets/dependencies/rickshaw/rickshaw.min.css' ), array(), GAWP_VERSION );
55
 
56
+ // Enqueue the datatables js file
57
+ wp_enqueue_script( 'datatables_js', self::get_asset_path( 'assets/dependencies/datatables/js/jquery.dataTables.min.js' ), array(), GAWP_VERSION, true );
58
 
59
+ // Enqueue the datatables css
60
+ wp_enqueue_style( 'datatables_css', self::get_asset_path( 'assets/dependencies/datatables/css/jquery.dataTables.min.css' ), array(), GAWP_VERSION );
61
 
62
+ Yoast_GA_Dashboards::get_instance()->add_dashboard_js_translations();
63
+ }
64
 
65
+ /**
66
+ * Getting the full path to given $asset
67
+ *
68
+ * @param string $asset
69
+ *
70
+ * @return string
71
+ */
72
+ public static function get_asset_path( $asset ) {
73
+ static $plugin_directory;
74
+
75
+ if ( $plugin_directory == null ) {
76
+ $plugin_directory = plugin_dir_url( GAWP_FILE );
77
  }
78
 
79
+ $return = $plugin_directory . $asset;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
+ return $return;
82
+ }
83
 
84
+ /**
85
+ * Check whether we can include the minified version or not
86
+ *
87
+ * @param string $ext
88
+ *
89
+ * @return string
90
+ */
91
+ private static function file_ext( $ext ) {
92
+ if ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) {
93
+ $ext = '.min' . $ext;
 
 
 
94
  }
95
 
96
+ return $ext;
97
  }
98
 
99
  }
admin/class-admin-form.php CHANGED
@@ -3,321 +3,318 @@
3
  /**
4
  * This class is for the backend
5
  */
6
- if ( ! class_exists( 'Yoast_GA_Admin_Form' ) ) {
7
 
8
- class Yoast_GA_Admin_Form {
9
 
10
- private static $form_namespace;
11
 
12
- /**
13
- * Create a form element to init a form
14
- *
15
- * @param string $namespace
16
- *
17
- * @return string
18
- */
19
- public static function create_form( $namespace ) {
20
- self::$form_namespace = $namespace;
21
 
22
- $action = admin_url( 'admin.php' );
23
- if ( isset( $_GET['page'] ) ) {
24
- $action .= '?page=' . $_GET['page'];
25
- }
26
-
27
- return '<form action="' . $action . '" method="post" id="yoast-ga-form-' . self::$form_namespace . '" class="yoast_ga_form">' . wp_nonce_field( 'save_settings', 'yoast_ga_nonce', null, false );
28
  }
29
 
30
-
31
- /**
32
- * Return the form end tag and the submit button
33
- *
34
- * @param string $button_label
35
- * @param string $name
36
- *
37
- * @return null|string
38
- */
39
- public static function end_form( $button_label = 'Save changes', $name = 'submit' ) {
40
- $output = null;
41
- $output .= '<div class="ga-form ga-form-input">';
42
- $output .= '<input type="submit" name="ga-form-' . $name . '" value="' . $button_label . '" class="button button-primary ga-form-submit" id="yoast-ga-form-submit-' . self::$form_namespace . '">';
43
- $output .= '</div></form>';
44
-
45
- return $output;
46
- }
47
 
48
 
49
- /**
50
- * Create a input form element with our labels and wrap them
51
- *
52
- * @param string $type
53
- * @param null|string $title
54
- * @param null|string $name
55
- * @param null|string $text_label
56
- * @param null|string $description
57
- *
58
- * @return null|string
59
- */
60
- public static function input( $type = 'text', $title = null, $name = null, $text_label = null, $description = null ) {
61
- $input = null;
62
- $id = str_replace( '[', '-', $name );
63
- $id = str_replace( ']', '', $id );
64
-
65
- $input_value = self::get_formfield_from_options( $name );
66
-
67
- $input .= '<div class="ga-form ga-form-input">';
68
- if ( ! is_null( $title ) ) {
69
- $input .= self::label( $id, $title, $type );
70
- }
71
 
72
- $attributes = array(
73
- 'type' => $type,
74
- 'id' => 'yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '',
75
- 'name' => $name,
76
- 'class' => 'ga-form ga-form-' . $type . ' ',
77
- );
78
 
79
- if ( $type == 'checkbox' ) {
80
- $attributes['value'] = '1';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
- if ( $input_value == 1 ) {
83
- $attributes['checked'] = 'checked';
84
- }
85
- } else {
86
- $attributes['value'] = stripslashes( $input_value );
87
- }
88
 
89
- $input .= '<input ' . self::parse_attributes( $attributes ) . ' />';
 
90
 
91
- if ( ! is_null( $text_label ) ) {
92
- $input .= '<label class="ga-form ga-form-' . $type . '-label" id="yoast-ga-form-label-' . $type . '-textlabel-' . self::$form_namespace . '-' . $id . '" for="yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $text_label . '</label>';
93
  }
 
 
 
94
 
95
- // If we get a description, append it to this select field in a new row
96
- if ( ! is_null( $description ) ) {
97
- $input .= self::show_help( $id, $description );
98
- }
99
 
100
- $input .= '</div>';
 
 
101
 
102
- return $input;
 
 
103
  }
104
 
105
- /**
106
- * Generate a select box
107
- *
108
- * @param string $title
109
- * @param string $name
110
- * @param array $values
111
- * @param null|string $description
112
- * @param bool $multiple
113
- * @param string $empty_text
114
- *
115
- * @return null|string
116
- */
117
- public static function select( $title, $name, $values, $description = null, $multiple = false, $empty_text = null ) {
118
- $select = null;
119
- $id = str_replace( '[', '-', $name );
120
- $id = str_replace( ']', '', $id );
121
-
122
- $select .= '<div class="ga-form ga-form-input">';
123
- if ( ! is_null( $title ) ) {
124
- $select .= self::label( $id, $title, 'select' ); //'<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
125
- }
126
 
127
- if ( $multiple ) {
128
- $select .= '<select multiple name="' . $name . '[]" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '" class="ga-multiple">';
129
- } else {
130
- $select .= '<select data-placeholder="' . $empty_text . '" name="' . $name . '" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '">';
131
- if ( ! is_null( $empty_text ) ) {
132
- $select .= '<option></option>';
133
- }
134
- }
135
- if ( count( $values ) >= 1 ) {
136
- $select_value = self::get_formfield_from_options( $name );
137
 
138
- foreach ( $values as $optgroup => $value ) {
139
- if ( ! empty( $value['items'] ) ) {
140
- $select .= self::create_optgroup( $optgroup, $value, $select_value );
141
- } else {
142
- $select .= self::option( $select_value, $value );
143
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
- }
 
 
 
 
 
146
  }
147
- $select .= '</select>';
 
 
148
 
149
- if ( ! is_null( $description ) ) {
150
- $select .= self::show_help( $id, $description );
151
- }
 
 
 
152
 
153
- $select .= '</div>';
 
 
154
 
155
- return $select;
 
156
  }
157
 
 
158
 
159
- /**
160
- * Generate a textarea field
161
- *
162
- * @param string $title
163
- * @param string $name
164
- * @param null|string $description
165
- *
166
- * @return null|string
167
- */
168
- public static function textarea( $title, $name, $description = null ) {
169
- $text = null;
170
- $id = Yoast_GA_Options::instance()->option_prefix . '_' . $name;
171
 
172
- $textarea_value = self::get_formfield_from_options( $name );
173
 
174
- $text .= '<div class="ga-form ga-form-input">';
 
 
 
 
 
 
 
 
 
 
 
175
 
176
- if ( ! is_null( $title ) ) {
177
- $text .= '<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . __( $title, 'google-analytics-for-wordpress' ) . ':</label>';
178
- }
179
 
180
- $text .= '<textarea rows="5" cols="60" name="' . $name . '" id="yoast-ga-form-textarea-' . self::$form_namespace . '-' . $id . '">' . stripslashes( $textarea_value ) . '</textarea>';
181
 
182
- if ( ! is_null( $description ) ) {
183
- $text .= self::show_help( $id, $description );
184
- }
185
 
186
- $text .= '</div>';
187
 
188
- return $text;
 
189
  }
190
 
191
- /**
192
- * Parsing a option string for select
193
- *
194
- * @param string $select_value
195
- * @param string $value
196
- *
197
- * @return string
198
- */
199
- private static function option( $select_value, $value ) {
200
-
201
- if ( is_array( $select_value ) ) {
202
- if ( in_array( $value['id'], $select_value ) ) {
203
- return '<option value="' . $value['id'] . '" selected="selected">' . stripslashes( $value['name'] ) . '</option>';
204
- } else {
205
- return '<option value="' . $value['id'] . '">' . stripslashes( $value['name'] ) . '</option>';
206
- }
 
 
207
  } else {
208
- return '<option value="' . $value['id'] . '" ' . selected( $select_value, $value['id'], false ) . '>' . stripslashes( $value['name'] ) . '</option>';
209
  }
 
 
210
  }
 
211
 
212
 
213
- /**
214
- * Show a question mark with help
215
- *
216
- * @param string $id
217
- * @param string $description
218
- *
219
- * @return string
220
- */
221
- public static function show_help( $id, $description ) {
222
- $help = '<img src="' . plugins_url( 'assets/img/question-mark.png', GAWP_FILE ) . '" class="alignleft yoast_help" id="' . esc_attr( $id . 'help' ) . '" alt="' . esc_attr( $description ) . '" />';
223
-
224
- return $help;
225
- }
226
 
 
 
227
 
228
- /**
229
- * Will parse the optgroups.
230
- *
231
- * @param array $values
232
- *
233
- * @return array
234
- */
235
- public static function parse_optgroups( $values ) {
236
- $optgroups = array();
237
- foreach ( $values as $key => $value ) {
238
- foreach ( $value['items'] AS $subitem ) {
239
- $optgroups[$subitem['name']]['items'] = $subitem['items'];
240
- }
241
 
 
 
 
 
 
 
 
 
 
 
 
 
242
  }
243
 
244
- return $optgroups;
245
  }
246
 
247
- /**
248
- * Creates a label
249
- *
250
- * @param $id
251
- * @param $title
252
- * @param $type
253
- *
254
- * @return string
255
- */
256
- private static function label( $id, $title, $type ) {
257
- return '<label class="ga-form ga-form-' . $type . '-label ga-form-label-left" id="yoast-ga-form-label-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
258
- }
259
-
260
- /**
261
- * Creates a optgroup with the items. If items contain items it will create a nested optgroup
262
- *
263
- * @param string $optgroup
264
- * @param array $value
265
- * @param array $select_value
266
- *
267
- * @return string
268
- */
269
- private static function create_optgroup( $optgroup, $value, $select_value ) {
270
- $optgroup = '<optgroup label="' . $optgroup . '">';
271
-
272
- foreach ( $value['items'] as $option ) {
273
- if ( ! empty( $option['items'] ) ) {
274
-
275
- $optgroup .= self::create_optgroup( $option['name'], $option, $select_value );
276
- } else {
277
- $optgroup .= self::option( $select_value, $option );
278
- }
279
- }
280
 
281
- $optgroup .= '</optgroup>';
 
 
 
 
 
 
 
 
 
 
 
282
 
283
- return $optgroup;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  }
285
 
 
286
 
287
- /**
288
- * Getting the value from the option, if it doesn't exist return empty string
289
- *
290
- * @param string $name
291
- *
292
- * @return string
293
- */
294
- private static function get_formfield_from_options( $name ) {
295
- static $options;
296
 
297
- if ( $options === null ) {
298
- $options = Yoast_GA_Options::instance()->get_options();
299
- }
300
 
301
- // Catch a notice if the option doesn't exist, yet
302
- return ( isset( $options[$name] ) ) ? $options[$name] : '';
 
 
 
 
 
 
 
 
 
 
303
  }
304
 
305
- /**
306
- * Parsing given array with attributes as an attribute string
307
- *
308
- * @param array $attributes_to_parse
309
- *
310
- * @return string
311
- */
312
- private static function parse_attributes( $attributes_to_parse ) {
313
- $parsed_attributes = '';
314
- foreach ( $attributes_to_parse as $attribute_name => $attribute_value ) {
315
- $parsed_attributes .= $attribute_name . '="' . $attribute_value . '" ';
316
- }
317
 
318
- return trim( $parsed_attributes );
 
 
 
 
 
 
 
 
 
 
319
  }
320
 
 
321
  }
322
 
323
  }
3
  /**
4
  * This class is for the backend
5
  */
 
6
 
7
+ class Yoast_GA_Admin_Form {
8
 
9
+ private static $form_namespace;
10
 
11
+ /**
12
+ * Create a form element to init a form
13
+ *
14
+ * @param string $namespace
15
+ *
16
+ * @return string
17
+ */
18
+ public static function create_form( $namespace ) {
19
+ self::$form_namespace = $namespace;
20
 
21
+ $action = admin_url( 'admin.php' );
22
+ if ( isset( $_GET['page'] ) ) {
23
+ $action .= '?page=' . $_GET['page'];
 
 
 
24
  }
25
 
26
+ return '<form action="' . $action . '" method="post" id="yoast-ga-form-' . self::$form_namespace . '" class="yoast_ga_form">' . wp_nonce_field( 'save_settings', 'yoast_ga_nonce', null, false );
27
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
 
30
+ /**
31
+ * Return the form end tag and the submit button
32
+ *
33
+ * @param string $button_label
34
+ * @param string $name
35
+ *
36
+ * @return null|string
37
+ */
38
+ public static function end_form( $button_label = 'Save changes', $name = 'submit' ) {
39
+ $output = null;
40
+ $output .= '<div class="ga-form ga-form-input">';
41
+ $output .= '<input type="submit" name="ga-form-' . $name . '" value="' . $button_label . '" class="button button-primary ga-form-submit" id="yoast-ga-form-submit-' . self::$form_namespace . '">';
42
+ $output .= '</div></form>';
43
+
44
+ return $output;
45
+ }
 
 
 
 
 
 
46
 
 
 
 
 
 
 
47
 
48
+ /**
49
+ * Create a input form element with our labels and wrap them
50
+ *
51
+ * @param string $type
52
+ * @param null|string $title
53
+ * @param null|string $name
54
+ * @param null|string $text_label
55
+ * @param null|string $description
56
+ *
57
+ * @return null|string
58
+ */
59
+ public static function input( $type = 'text', $title = null, $name = null, $text_label = null, $description = null ) {
60
+ $input = null;
61
+ $id = str_replace( '[', '-', $name );
62
+ $id = str_replace( ']', '', $id );
63
+
64
+ $input_value = self::get_formfield_from_options( $name );
65
+
66
+ $input .= '<div class="ga-form ga-form-input">';
67
+ if ( ! is_null( $title ) ) {
68
+ $input .= self::label( $id, $title, $type );
69
+ }
70
 
71
+ $attributes = array(
72
+ 'type' => $type,
73
+ 'id' => 'yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '',
74
+ 'name' => $name,
75
+ 'class' => 'ga-form ga-form-' . $type . ' ',
76
+ );
77
 
78
+ if ( $type == 'checkbox' ) {
79
+ $attributes['value'] = '1';
80
 
81
+ if ( $input_value == 1 ) {
82
+ $attributes['checked'] = 'checked';
83
  }
84
+ } else {
85
+ $attributes['value'] = stripslashes( $input_value );
86
+ }
87
 
88
+ $input .= '<input ' . self::parse_attributes( $attributes ) . ' />';
 
 
 
89
 
90
+ if ( ! is_null( $text_label ) ) {
91
+ $input .= '<label class="ga-form ga-form-' . $type . '-label" id="yoast-ga-form-label-' . $type . '-textlabel-' . self::$form_namespace . '-' . $id . '" for="yoast-ga-form-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $text_label . '</label>';
92
+ }
93
 
94
+ // If we get a description, append it to this select field in a new row
95
+ if ( ! is_null( $description ) ) {
96
+ $input .= self::show_help( $id, $description );
97
  }
98
 
99
+ $input .= '</div>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
+ return $input;
102
+ }
 
 
 
 
 
 
 
 
103
 
104
+ /**
105
+ * Generate a select box
106
+ *
107
+ * @param string $title
108
+ * @param string $name
109
+ * @param array $values
110
+ * @param null|string $description
111
+ * @param bool $multiple
112
+ * @param string $empty_text
113
+ *
114
+ * @return null|string
115
+ */
116
+ public static function select( $title, $name, $values, $description = null, $multiple = false, $empty_text = null ) {
117
+ $select = null;
118
+ $id = str_replace( '[', '-', $name );
119
+ $id = str_replace( ']', '', $id );
120
+
121
+ $select .= '<div class="ga-form ga-form-input">';
122
+ if ( ! is_null( $title ) ) {
123
+ $select .= self::label( $id, $title, 'select' ); //'<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
124
+ }
125
 
126
+ if ( $multiple ) {
127
+ $select .= '<select multiple name="' . $name . '[]" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '" class="ga-multiple">';
128
+ } else {
129
+ $select .= '<select data-placeholder="' . $empty_text . '" name="' . $name . '" id="yoast-ga-form-select-' . self::$form_namespace . '-' . $id . '">';
130
+ if ( ! is_null( $empty_text ) ) {
131
+ $select .= '<option></option>';
132
  }
133
+ }
134
+ if ( count( $values ) >= 1 ) {
135
+ $select_value = self::get_formfield_from_options( $name );
136
 
137
+ foreach ( $values as $optgroup => $value ) {
138
+ if ( ! empty( $value['items'] ) ) {
139
+ $select .= self::create_optgroup( $optgroup, $value, $select_value );
140
+ } else {
141
+ $select .= self::option( $select_value, $value );
142
+ }
143
 
144
+ }
145
+ }
146
+ $select .= '</select>';
147
 
148
+ if ( ! is_null( $description ) ) {
149
+ $select .= self::show_help( $id, $description );
150
  }
151
 
152
+ $select .= '</div>';
153
 
154
+ return $select;
155
+ }
 
 
 
 
 
 
 
 
 
 
156
 
 
157
 
158
+ /**
159
+ * Generate a textarea field
160
+ *
161
+ * @param string $title
162
+ * @param string $name
163
+ * @param null|string $description
164
+ *
165
+ * @return null|string
166
+ */
167
+ public static function textarea( $title, $name, $description = null ) {
168
+ $text = null;
169
+ $id = Yoast_GA_Options::instance()->option_prefix . '_' . $name;
170
 
171
+ $textarea_value = self::get_formfield_from_options( $name );
 
 
172
 
173
+ $text .= '<div class="ga-form ga-form-input">';
174
 
175
+ if ( ! is_null( $title ) ) {
176
+ $text .= '<label class="ga-form ga-form-select-label ga-form-label-left" id="yoast-ga-form-label-select-' . self::$form_namespace . '-' . $id . '">' . __( $title, 'google-analytics-for-wordpress' ) . ':</label>';
177
+ }
178
 
179
+ $text .= '<textarea rows="5" cols="60" name="' . $name . '" id="yoast-ga-form-textarea-' . self::$form_namespace . '-' . $id . '">' . stripslashes( $textarea_value ) . '</textarea>';
180
 
181
+ if ( ! is_null( $description ) ) {
182
+ $text .= self::show_help( $id, $description );
183
  }
184
 
185
+ $text .= '</div>';
186
+
187
+ return $text;
188
+ }
189
+
190
+ /**
191
+ * Parsing a option string for select
192
+ *
193
+ * @param string $select_value
194
+ * @param string $value
195
+ *
196
+ * @return string
197
+ */
198
+ private static function option( $select_value, $value ) {
199
+
200
+ if ( is_array( $select_value ) ) {
201
+ if ( in_array( $value['id'], $select_value ) ) {
202
+ return '<option value="' . $value['id'] . '" selected="selected">' . stripslashes( $value['name'] ) . '</option>';
203
  } else {
204
+ return '<option value="' . $value['id'] . '">' . stripslashes( $value['name'] ) . '</option>';
205
  }
206
+ } else {
207
+ return '<option value="' . $value['id'] . '" ' . selected( $select_value, $value['id'], false ) . '>' . stripslashes( $value['name'] ) . '</option>';
208
  }
209
+ }
210
 
211
 
212
+ /**
213
+ * Show a question mark with help
214
+ *
215
+ * @param string $id
216
+ * @param string $description
217
+ *
218
+ * @return string
219
+ */
220
+ public static function show_help( $id, $description ) {
221
+ $help = '<img src="' . plugins_url( 'assets/img/question-mark.png', GAWP_FILE ) . '" class="alignleft yoast_help" id="' . esc_attr( $id . 'help' ) . '" alt="' . esc_attr( $description ) . '" />';
 
 
 
222
 
223
+ return $help;
224
+ }
225
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
 
227
+ /**
228
+ * Will parse the optgroups.
229
+ *
230
+ * @param array $values
231
+ *
232
+ * @return array
233
+ */
234
+ public static function parse_optgroups( $values ) {
235
+ $optgroups = array();
236
+ foreach ( $values as $key => $value ) {
237
+ foreach ( $value['items'] AS $subitem ) {
238
+ $optgroups[$subitem['name']]['items'] = $subitem['items'];
239
  }
240
 
 
241
  }
242
 
243
+ return $optgroups;
244
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
+ /**
247
+ * Creates a label
248
+ *
249
+ * @param $id
250
+ * @param $title
251
+ * @param $type
252
+ *
253
+ * @return string
254
+ */
255
+ private static function label( $id, $title, $type ) {
256
+ return '<label class="ga-form ga-form-' . $type . '-label ga-form-label-left" id="yoast-ga-form-label-' . $type . '-' . self::$form_namespace . '-' . $id . '">' . $title . ':</label>';
257
+ }
258
 
259
+ /**
260
+ * Creates a optgroup with the items. If items contain items it will create a nested optgroup
261
+ *
262
+ * @param string $optgroup
263
+ * @param array $value
264
+ * @param array $select_value
265
+ *
266
+ * @return string
267
+ */
268
+ private static function create_optgroup( $optgroup, $value, $select_value ) {
269
+ $optgroup = '<optgroup label="' . $optgroup . '">';
270
+
271
+ foreach ( $value['items'] as $option ) {
272
+ if ( ! empty( $option['items'] ) ) {
273
+
274
+ $optgroup .= self::create_optgroup( $option['name'], $option, $select_value );
275
+ } else {
276
+ $optgroup .= self::option( $select_value, $option );
277
+ }
278
  }
279
 
280
+ $optgroup .= '</optgroup>';
281
 
282
+ return $optgroup;
283
+ }
 
 
 
 
 
 
 
284
 
 
 
 
285
 
286
+ /**
287
+ * Getting the value from the option, if it doesn't exist return empty string
288
+ *
289
+ * @param string $name
290
+ *
291
+ * @return string
292
+ */
293
+ private static function get_formfield_from_options( $name ) {
294
+ static $options;
295
+
296
+ if ( $options === null ) {
297
+ $options = Yoast_GA_Options::instance()->get_options();
298
  }
299
 
300
+ // Catch a notice if the option doesn't exist, yet
301
+ return ( isset( $options[$name] ) ) ? $options[$name] : '';
302
+ }
 
 
 
 
 
 
 
 
 
303
 
304
+ /**
305
+ * Parsing given array with attributes as an attribute string
306
+ *
307
+ * @param array $attributes_to_parse
308
+ *
309
+ * @return string
310
+ */
311
+ private static function parse_attributes( $attributes_to_parse ) {
312
+ $parsed_attributes = '';
313
+ foreach ( $attributes_to_parse as $attribute_name => $attribute_value ) {
314
+ $parsed_attributes .= $attribute_name . '="' . $attribute_value . '" ';
315
  }
316
 
317
+ return trim( $parsed_attributes );
318
  }
319
 
320
  }
admin/class-admin-menu.php CHANGED
@@ -1,178 +1,241 @@
1
  <?php
 
2
  /**
3
  * This class is for the backend, extendable for all child classes
4
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- if ( ! class_exists( 'Yoast_GA_Admin_Menu' ) ) {
 
 
7
 
8
- class Yoast_GA_Admin_Menu extends Yoast_GA_Options {
 
9
 
 
 
 
 
10
  /**
11
- * The property used for storing target object (class admin)
12
  *
13
- * @var
14
  */
15
- private $target_object;
16
 
17
- /**
18
- * Setting the target_object and adding actions
19
- *
20
- * @param object $target_object
21
- */
22
- public function __construct( $target_object ) {
23
 
24
- $this->target_object = $target_object;
25
 
26
- add_action( 'admin_menu', array( $this, 'create_admin_menu' ), 10 );
 
 
27
 
28
- require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
- if ( is_plugin_active_for_network( GAWP_PATH ) ) {
31
- add_action( 'network_admin_menu', array( $this, 'create_admin_menu' ), 5 );
32
- }
 
 
 
 
 
 
 
 
 
33
  }
34
 
35
- /**
36
- * Create the admin menu
37
- *
38
- * @todo, we need to implement a new icon for this, currently we're using the WP seo icon
39
- */
40
- public function create_admin_menu() {
41
- /**
42
- * Filter: 'wpga_menu_on_top' - Allows filtering of menu location of the GA plugin, if false is returned, it moves to bottom.
43
- *
44
- * @api book unsigned
45
- */
46
- $on_top = apply_filters( 'wpga_menu_on_top', true );
47
-
48
- // Base 64 encoded SVG image
49
- $icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgWw0KCTwhRU5USVRZIG5zX2Zsb3dzICJodHRwOi8vbnMuYWRvYmUuY29tL0Zsb3dzLzEuMC8iPg0KCTwhRU5USVRZIG5zX2V4dGVuZCAiaHR0cDovL25zLmFkb2JlLmNvbS9FeHRlbnNpYmlsaXR5LzEuMC8iPg0KCTwhRU5USVRZIG5zX2FpICJodHRwOi8vbnMuYWRvYmUuY29tL0Fkb2JlSWxsdXN0cmF0b3IvMTAuMC8iPg0KCTwhRU5USVRZIG5zX2dyYXBocyAiaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyI+DQpdPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYWFnXzEiIHhtbG5zOng9IiZuc19leHRlbmQ7IiB4bWxuczppPSImbnNfYWk7IiB4bWxuczpncmFwaD0iJm5zX2dyYXBoczsiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOmE9Imh0dHA6Ly9ucy5hZG9iZS5jb20vQWRvYmVTVkdWaWV3ZXJFeHRlbnNpb25zLzMuMC8iDQoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDAgMzEuODkiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQwIDMxLjg5IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQwLDEyLjUyNEM0MCw1LjYwOCwzMS40NjksMCwyMCwwQzguNTMsMCwwLDUuNjA4LDAsMTIuNTI0YzAsNS41Niw1LjI0MywxMC4yNzIsMTMuNTU3LDExLjkwN3YtNC4wNjUNCgljMCwwLDAuMDQtMS0wLjI4LTEuOTJjLTAuMzItMC45MjEtMS43Ni0zLjAwMS0xLjc2LTUuMTIxYzAtMi4xMjEsMi41NjEtOS41NjMsNS4xMjItMTAuNDQ0Yy0wLjQsMS4yMDEtMC4zMiw3LjY4My0wLjMyLDcuNjgzDQoJczEuNCwyLjcyLDQuNjQxLDIuNzJjMy4yNDIsMCw0LjUxMS0xLjc2LDQuNzE1LTIuMmMwLjIwNi0wLjQ0LDAuODQ2LTguNzIzLDAuODQ2LTguNzIzczQuMDgyLDQuNDAyLDMuNjgyLDkuMzYzDQoJYy0wLjQwMSw0Ljk2Mi00LjQ4Miw3LjIwMy02LjEyMiw5LjEyM2MtMS4yODYsMS41MDUtMi4yMjQsMy4xMy0yLjYyOSw0LjE2OGMwLjgwMS0wLjAzNCwxLjU4Ny0wLjA5OCwyLjM2MS0wLjE4NGw5LjE1MSw3LjA1OQ0KCWwtNC44ODQtNy44M0MzNS41MzUsMjIuMTYxLDQwLDE3LjcxMyw0MCwxMi41MjR6Ii8+DQo8L2c+DQo8L3N2Zz4=';
50
-
51
- $menu_name = is_network_admin() ? 'extensions' : 'dashboard';
52
-
53
- // Add main page
54
- add_menu_page(
55
- __( 'Yoast Google Analytics:', 'google-analytics-for-wordpress' ) . ' ' . __( 'General settings', 'google-analytics-for-wordpress' ), __( 'Analytics', 'google-analytics-for-wordpress' ), 'manage_options', 'yst_ga_' . $menu_name,
56
- array(
57
- $this->target_object,
58
- 'load_page',
59
- ),
60
- $icon_svg,
61
- $on_top ? '2.00013467543' : '100.00013467543'
62
- );
63
-
64
- $this->add_submenu_pages();
65
  }
66
 
67
- /**
68
- * Prepares an array that can be used to add a submenu page to the Google Analytics for Wordpress menu
69
- *
70
- * @param $submenu_name
71
- * @param $font_color
72
- *
73
- * @return array
74
- */
75
- private function prepare_submenu_page( $submenu_name, $font_color ) {
76
- $menu_title = $this->parse_menu_title( $submenu_name, $font_color );
77
- $submenu_page = array(
78
- 'parent_slug' => 'yst_ga_dashboard',
79
- 'page_title' => __( 'Yoast Google Analytics:', 'google-analytics-for-wordpress' ) . ' ' . __( ucfirst( $submenu_name ), 'google-analytics-for-wordpress' ),
80
- 'menu_title' => $menu_title,
81
- 'capability' => 'manage_options',
82
- 'menu_slug' => 'yst_ga_' . $submenu_name,
83
- 'submenu_function' => array( $this->target_object, 'load_page' ),
84
- );
85
 
86
- return $submenu_page;
 
 
 
 
 
 
 
 
 
 
 
87
  }
 
88
 
89
- /**
90
- * Parsing the menutitle
91
- *
92
- * @param string $submenu_name
93
- * @param string $font_color
94
- *
95
- * @return string
96
- */
97
- private function parse_menu_title( $submenu_name, $font_color ) {
98
- $menu_title = __( ucfirst( $submenu_name ), 'google-analytics-for-wordpress' );
99
- if ( ! empty( $font_color ) ) {
100
- $menu_title = __( '<span style="color:' . $font_color . '">' . $menu_title . '</span>', 'google-analytics-for-wordpress' );
101
- }
102
-
103
- return $menu_title;
 
 
 
 
 
 
104
  }
105
 
106
- /**
107
- * Adds a submenu page to the Google Analytics for WordPress menu
108
- *
109
- * @param $submenu_page
110
- */
111
- private function add_submenu_page( $submenu_page ) {
112
- $page = add_submenu_page( $submenu_page['parent_slug'], $submenu_page['page_title'], $submenu_page['menu_title'], $submenu_page['capability'], $submenu_page['menu_slug'], $submenu_page['submenu_function'] );
113
- $is_not_dashboard = ( 'yst_ga_settings' === $submenu_page['menu_slug'] || 'yst_ga_extensions' === $submenu_page['menu_slug'] );
114
 
115
- $this->add_assets( $page, $is_not_dashboard );
 
 
 
 
 
 
 
 
 
 
116
  }
117
 
118
- /**
119
- * Adding stylesheets and based on $is_not_dashboard maybe some more styles and scripts.
120
- *
121
- * @param string $page
122
- * @param boolean $is_not_dashboard
123
- */
124
- private function add_assets( $page, $is_not_dashboard ) {
125
- add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_styles' ) );
126
 
127
- add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_settings_styles' ) );
128
- add_action( 'admin_print_scripts-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_scripts' ) );
129
- if ( ! $is_not_dashboard ) {
130
- Yoast_GA_Admin_Assets::enqueue_dashboard_assets();
131
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
 
133
 
 
 
 
 
 
 
 
 
 
134
  /**
135
- * Prepares and adds submenu pages to the Google Analytics for Wordpress menu:
136
- * - Dashboard
137
- * - Settings
138
- * - Extensions
 
 
 
 
 
 
 
139
  *
140
- * @return array
141
  */
142
- private function add_submenu_pages() {
143
- /**
144
- * Array structure:
145
- *
146
- * array(
147
- * $submenu_name => $font_color,
148
- * ..,
149
- * ..,
150
- * )
151
- *
152
- * $font_color can be left empty.
153
- *
154
- */
155
- $submenu_types = array(
156
- 'extensions' => '#f18500',
 
 
 
157
  );
 
158
 
159
- if ( ! is_network_admin() ) {
160
- $submenu_types = array_merge(
161
- array(
162
- 'dashboard' => '',
163
- 'settings' => '',
164
- ),
165
- $submenu_types
166
- );
167
- }
168
 
169
- foreach ( $submenu_types as $submenu_name => $font_color ) {
170
- $submenu_page = $this->prepare_submenu_page( $submenu_name, $font_color );
171
- $this->add_submenu_page( $submenu_page );
 
 
172
  }
 
173
  }
174
-
175
-
176
  }
177
-
178
  }
1
  <?php
2
+
3
  /**
4
  * This class is for the backend, extendable for all child classes
5
  */
6
+ class Yoast_GA_Admin_Menu extends Yoast_GA_Options {
7
+
8
+ /**
9
+ * The property used for storing target object (class admin)
10
+ *
11
+ * @var
12
+ */
13
+ private $target_object;
14
+
15
+ /**
16
+ * The dashboards disabled bool
17
+ *
18
+ * @var
19
+ */
20
+ private $dashboards_disabled;
21
+
22
+ /**
23
+ * Setting the target_object and adding actions
24
+ *
25
+ * @param object $target_object
26
+ */
27
+ public function __construct( $target_object ) {
28
+
29
+ $this->target_object = $target_object;
30
+
31
+ add_action( 'admin_menu', array( $this, 'create_admin_menu' ), 10 );
32
+
33
+ if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
34
+ require_once( ABSPATH . '/wp-admin/includes/plugin.php' );
35
+ }
36
 
37
+ if ( is_plugin_active_for_network( GAWP_PATH ) ) {
38
+ add_action( 'network_admin_menu', array( $this, 'create_admin_menu' ), 5 );
39
+ }
40
 
41
+ $this->dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
42
+ }
43
 
44
+ /**
45
+ * Create the admin menu
46
+ */
47
+ public function create_admin_menu() {
48
  /**
49
+ * Filter: 'wpga_menu_on_top' - Allows filtering of menu location of the GA plugin, if false is returned, it moves to bottom.
50
  *
51
+ * @api book unsigned
52
  */
 
53
 
54
+ // Base 64 encoded SVG image
55
+ $icon_svg = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCIgWw0KCTwhRU5USVRZIG5zX2Zsb3dzICJodHRwOi8vbnMuYWRvYmUuY29tL0Zsb3dzLzEuMC8iPg0KCTwhRU5USVRZIG5zX2V4dGVuZCAiaHR0cDovL25zLmFkb2JlLmNvbS9FeHRlbnNpYmlsaXR5LzEuMC8iPg0KCTwhRU5USVRZIG5zX2FpICJodHRwOi8vbnMuYWRvYmUuY29tL0Fkb2JlSWxsdXN0cmF0b3IvMTAuMC8iPg0KCTwhRU5USVRZIG5zX2dyYXBocyAiaHR0cDovL25zLmFkb2JlLmNvbS9HcmFwaHMvMS4wLyI+DQpdPg0KPHN2ZyB2ZXJzaW9uPSIxLjEiIGlkPSJMYWFnXzEiIHhtbG5zOng9IiZuc19leHRlbmQ7IiB4bWxuczppPSImbnNfYWk7IiB4bWxuczpncmFwaD0iJm5zX2dyYXBoczsiDQoJIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOmE9Imh0dHA6Ly9ucy5hZG9iZS5jb20vQWRvYmVTVkdWaWV3ZXJFeHRlbnNpb25zLzMuMC8iDQoJIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNDAgMzEuODkiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDQwIDMxLjg5IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KPHBhdGggZmlsbD0iI0ZGRkZGRiIgZD0iTTQwLDEyLjUyNEM0MCw1LjYwOCwzMS40NjksMCwyMCwwQzguNTMsMCwwLDUuNjA4LDAsMTIuNTI0YzAsNS41Niw1LjI0MywxMC4yNzIsMTMuNTU3LDExLjkwN3YtNC4wNjUNCgljMCwwLDAuMDQtMS0wLjI4LTEuOTJjLTAuMzItMC45MjEtMS43Ni0zLjAwMS0xLjc2LTUuMTIxYzAtMi4xMjEsMi41NjEtOS41NjMsNS4xMjItMTAuNDQ0Yy0wLjQsMS4yMDEtMC4zMiw3LjY4My0wLjMyLDcuNjgzDQoJczEuNCwyLjcyLDQuNjQxLDIuNzJjMy4yNDIsMCw0LjUxMS0xLjc2LDQuNzE1LTIuMmMwLjIwNi0wLjQ0LDAuODQ2LTguNzIzLDAuODQ2LTguNzIzczQuMDgyLDQuNDAyLDMuNjgyLDkuMzYzDQoJYy0wLjQwMSw0Ljk2Mi00LjQ4Miw3LjIwMy02LjEyMiw5LjEyM2MtMS4yODYsMS41MDUtMi4yMjQsMy4xMy0yLjYyOSw0LjE2OGMwLjgwMS0wLjAzNCwxLjU4Ny0wLjA5OCwyLjM2MS0wLjE4NGw5LjE1MSw3LjA1OQ0KCWwtNC44ODQtNy44M0MzNS41MzUsMjIuMTYxLDQwLDE3LjcxMyw0MCwxMi41MjR6Ii8+DQo8L2c+DQo8L3N2Zz4=';
 
 
 
 
56
 
57
+ $menu_name = is_network_admin() ? 'extensions' : 'dashboard';
58
 
59
+ if ( $this->dashboards_disabled ) {
60
+ $menu_name = 'settings';
61
+ }
62
 
63
+ // Add main page
64
+ add_menu_page(
65
+ __( 'Yoast Google Analytics:', 'google-analytics-for-wordpress' ) . ' ' . __( 'General settings', 'google-analytics-for-wordpress' ), __( 'Analytics', 'google-analytics-for-wordpress' ), 'manage_options', 'yst_ga_' . $menu_name,
66
+ array(
67
+ $this->target_object,
68
+ 'load_page',
69
+ ),
70
+ $icon_svg,
71
+ $this->get_menu_position()
72
+ );
73
+
74
+ $this->add_submenu_pages();
75
+ }
76
 
77
+ /**
78
+ * Get the menu position of the Analytics item
79
+ *
80
+ * @return string
81
+ */
82
+ private function get_menu_position() {
83
+ $on_top = apply_filters( 'wpga_menu_on_top', true );
84
+
85
+ if ( $on_top ) {
86
+ $position = $this->get_menu_position_value( 'top' );
87
+ } else {
88
+ $position = $this->get_menu_position_value( 'bottom' );
89
  }
90
 
91
+ // If the dashboards are disabled, force the menu item to stay at the bottom of the menu
92
+ if ( $this->dashboards_disabled ) {
93
+ $position = $this->get_menu_position_value( 'bottom' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
 
96
+ return $position;
97
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
+ /**
100
+ * Get the top or bottom menu location number
101
+ *
102
+ * @param $location
103
+ *
104
+ * @return string
105
+ */
106
+ private function get_menu_position_value( $location ) {
107
+ if ( $location == 'top' ) {
108
+ return '2.00013467543';
109
+ } else {
110
+ return '100.00013467543';
111
  }
112
+ }
113
 
114
+ /**
115
+ * Prepares an array that can be used to add a submenu page to the Google Analytics for Wordpress menu
116
+ *
117
+ * @param $submenu_name
118
+ * @param $font_color
119
+ *
120
+ * @return array
121
+ */
122
+ private function prepare_submenu_page( $submenu_name, $font_color = '' ) {
123
+ $menu_title = $this->parse_menu_title( $submenu_name, $font_color );
124
+ $submenu_page = array(
125
+ 'parent_slug' => 'yst_ga_dashboard',
126
+ 'page_title' => __( 'Yoast Google Analytics:', 'google-analytics-for-wordpress' ) . ' ' . $submenu_name,
127
+ 'menu_title' => $menu_title,
128
+ 'capability' => 'manage_options',
129
+ 'menu_slug' => 'yst_ga_' . strtolower( $submenu_name ),
130
+ 'submenu_function' => array( $this->target_object, 'load_page' ),
131
+ );
132
+
133
+ if ( $this->dashboards_disabled ) {
134
+ $submenu_page['parent_slug'] = 'yst_ga_settings';
135
  }
136
 
137
+ return $submenu_page;
138
+ }
 
 
 
 
 
 
139
 
140
+ /**
141
+ * Parsing the menutitle
142
+ *
143
+ * @param string $menu_title
144
+ * @param string $font_color
145
+ *
146
+ * @return string
147
+ */
148
+ private function parse_menu_title( $menu_title, $font_color ) {
149
+ if ( ! empty( $font_color ) ) {
150
+ $menu_title = '<span style="color:' . $font_color . '">' . $menu_title . '</span>';
151
  }
152
 
153
+ return $menu_title;
154
+ }
 
 
 
 
 
 
155
 
156
+ /**
157
+ * Adds a submenu page to the Google Analytics for WordPress menu
158
+ *
159
+ * @param $submenu_page
160
+ */
161
+ private function add_submenu_page( $submenu_page ) {
162
+ $page = add_submenu_page( $submenu_page['parent_slug'], $submenu_page['page_title'], $submenu_page['menu_title'], $submenu_page['capability'], $submenu_page['menu_slug'], $submenu_page['submenu_function'] );
163
+ $is_not_dashboard = ( 'yst_ga_settings' === $submenu_page['menu_slug'] || 'yst_ga_extensions' === $submenu_page['menu_slug'] );
164
+
165
+ $this->add_assets( $page, $is_not_dashboard );
166
+ }
167
+
168
+ /**
169
+ * Adding stylesheets and based on $is_not_dashboard maybe some more styles and scripts.
170
+ *
171
+ * @param string $page
172
+ * @param boolean $is_not_dashboard
173
+ */
174
+ private function add_assets( $page, $is_not_dashboard ) {
175
+ add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_styles' ) );
176
+
177
+ add_action( 'admin_print_styles-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_settings_styles' ) );
178
+ add_action( 'admin_print_scripts-' . $page, array( 'Yoast_GA_Admin_Assets', 'enqueue_scripts' ) );
179
+ if ( ! $is_not_dashboard ) {
180
+ Yoast_GA_Admin_Assets::enqueue_dashboard_assets();
181
  }
182
+ }
183
 
184
+ /**
185
+ * Prepares and adds submenu pages to the Google Analytics for Wordpress menu:
186
+ * - Dashboard
187
+ * - Settings
188
+ * - Extensions
189
+ *
190
+ * @return array
191
+ */
192
+ private function add_submenu_pages() {
193
  /**
194
+ * Array structure:
195
+ *
196
+ * array(
197
+ * $submenu_name => array(
198
+ * 'color' => $font_color,
199
+ * 'label' => __( 'text-label', 'google-analytics-for-wordpress' ),
200
+ * ),
201
+ * ..,
202
+ * )
203
+ *
204
+ * $font_color can be left empty.
205
  *
 
206
  */
207
+ $submenu_types = array(
208
+ 'extensions' => array(
209
+ 'color' => '#f18500',
210
+ 'label' => __( 'Extensions', 'google-analytics-for-wordpress' ),
211
+ ),
212
+ );
213
+
214
+ if ( ! is_network_admin() ) {
215
+ $submenu_types = array_merge(
216
+ array(
217
+ 'dashboard' => array(
218
+ 'label' => __( 'Dashboard', 'google-analytics-for-wordpress' ),
219
+ ),
220
+ 'settings' => array(
221
+ 'label' => __( 'Settings', 'google-analytics-for-wordpress' ),
222
+ ),
223
+ ),
224
+ $submenu_types
225
  );
226
+ }
227
 
228
+ if ( $this->dashboards_disabled ) {
229
+ unset( $submenu_types['dashboard'] );
230
+ }
 
 
 
 
 
 
231
 
232
+ foreach ( $submenu_types as $submenu_key => $submenu ) {
233
+ if ( isset( $submenu['color'] ) ) {
234
+ $submenu_page = $this->prepare_submenu_page( $submenu['label'], $submenu['color'] );
235
+ } else {
236
+ $submenu_page = $this->prepare_submenu_page( $submenu['label'] );
237
  }
238
+ $this->add_submenu_page( $submenu_page );
239
  }
 
 
240
  }
 
241
  }
admin/class-admin.php CHANGED
@@ -1,514 +1,493 @@
1
  <?php
 
2
  /**
3
  * This class is for the backend, extendable for all child classes
4
  */
 
5
 
6
- if ( ! class_exists( 'Yoast_GA_Admin' ) ) {
7
-
8
- class Yoast_GA_Admin extends Yoast_GA_Options {
9
-
10
- /**
11
- * Store the API instance
12
- *
13
- * @var
14
- */
15
- public $api;
16
 
17
- public function __construct() {
18
- parent::__construct();
19
 
20
- add_action( 'plugins_loaded', array( $this, 'init_ga' ) );
21
- add_action( 'admin_init', array( $this, 'init_settings' ) );
22
- }
23
 
24
- /**
25
- * Init function when the plugin is loaded
26
- */
27
- public function init_ga() {
28
 
29
- new Yoast_GA_Admin_Menu( $this );
30
 
31
- add_filter( 'plugin_action_links_' . plugin_basename( GAWP_FILE ), array( $this, 'add_action_links' ) );
32
 
33
- }
34
 
35
- /**
36
- * Init function for the settings of GA
37
- */
38
- public function init_settings() {
39
- $this->options = $this->get_options();
40
- $this->api = Yoast_Api_Libs::load_api_libraries( array( 'google', 'googleanalytics' ) );
 
41
 
 
 
42
 
43
- // Listener for reconnecting with google analytics
44
- $this->google_analytics_listener();
 
45
 
46
- if ( is_null( $this->get_tracking_code() ) && $this->show_admin_warning() ) {
47
- add_action( 'admin_notices', array( $this, 'config_warning' ) );
48
- }
 
 
49
 
50
- $last_run = get_option( 'yst_ga_last_wp_run' );
51
- if ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 48 ) {
52
- // Show error, something went wrong
53
- if ( ! is_null( $this->get_tracking_code() ) && empty( $this->options['manual_ua_code_field'] ) && $this->show_admin_dashboard_warning() ) {
54
- add_action( 'admin_notices', array( $this, 'warning_fetching_data' ) );
55
- }
56
  }
57
 
58
- if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
59
- if ( ! function_exists( 'wp_verify_nonce' ) ) {
60
- require_once( ABSPATH . 'wp-includes/pluggable.php' );
61
  }
62
 
63
- if ( isset( $_POST['ga-form-settings'] ) && wp_verify_nonce( $_POST['yoast_ga_nonce'], 'save_settings' ) ) {
64
- if ( ! isset ( $_POST['ignore_users'] ) ) {
65
- $_POST['ignore_users'] = array();
66
- }
67
 
68
- // Post submitted and verified with our nonce
69
- $this->save_settings( $_POST );
70
  }
71
- }
72
-
73
- /**
74
- * Show the notifications if we have one
75
- */
76
- $this->show_notification( 'ga_notifications' );
77
 
78
- // Load the Google Analytics Dashboards functionality
79
- $dashboards = Yoast_GA_Dashboards::get_instance();
80
- $dashboards->init_dashboards( $this->get_current_profile() );
81
- }
82
-
83
- /**
84
- * Throw a warning if no UA code is set.
85
- */
86
- public function config_warning() {
87
- echo '<div class="error"><p>' . sprintf( __( 'Please configure your %sGoogle Analytics settings%s!', 'google-analytics-for-wordpress' ), '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">', '</a>' ) . '</p></div>';
88
  }
89
 
90
  /**
91
- * Throw a warning when the fetching failed
92
  */
93
- public function warning_fetching_data() {
94
- echo '<div class="error"><p>' . sprintf( __( 'Failed to fetch the new data from Google Analytics. You might need to %sreauthenticate%s.', 'google-analytics-for-wordpress' ), '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">', '</a>' ) . '</p></div>';
95
- }
96
 
97
- /**
98
- * This function saves the settings in the option field and returns a wp success message on success
99
- *
100
- * @param $data
101
- */
102
- public function save_settings( $data ) {
103
 
104
- unset( $data['google_auth_code'] );
 
 
 
 
 
105
 
106
- foreach ( $data as $key => $value ) {
107
- if ( $key != 'return_tab' ) {
108
- if ( $key != 'custom_code' && is_string( $value ) ) {
109
- $value = strip_tags( $value );
110
- }
111
- $this->options[$key] = $value;
112
- }
113
- }
114
 
115
- // Check checkboxes, on a uncheck they won't be posted to this function
116
- $defaults = $this->default_ga_values();
117
- foreach ( $defaults[$this->option_prefix] as $key => $value ) {
118
- if ( ! isset( $data[$key] ) ) {
119
- // If no data was passed in, set it to the default.
120
- $this->options[$key] = $value;
121
  }
 
122
  }
 
123
 
124
- if ( ! empty( $this->options['analytics_profile'] ) ) {
125
- $this->options['analytics_profile_code'] = $this->get_ua_code_from_profile( $this->options['analytics_profile'] );
 
 
 
 
126
  }
 
127
 
128
- if ( $this->update_option( $this->options ) ) {
129
- // Success, add a new notification
130
- $this->add_notification( 'ga_notifications', array(
131
- 'type' => 'success',
132
- 'description' => __( 'Settings saved!', 'google-analytics-for-wordpress' ),
133
- ) );
134
-
135
- } else {
136
- // Fail, add a new notification
137
- $this->add_notification( 'ga_notifications', array(
138
- 'type' => 'error',
139
- 'description' => __( 'There were no changes to save, please try again.', 'google-analytics-for-wordpress' ),
140
- ) );
141
- }
142
 
143
- #redirect
144
- wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $data['return_tab'], 301 );
145
- exit;
 
 
 
 
 
 
 
 
 
 
146
  }
147
 
148
- /**
149
- * Run a this deactivation hook on deactivation of GA. When this happens we'll
150
- * remove the options for the profiles and the refresh token.
151
- */
152
- public static function ga_deactivation_hook() {
153
- // Remove the refresh token
154
- delete_option( 'yoast-ga-refresh_token' );
155
 
156
- // Remove the ga accounts and response
157
- delete_option( 'yst_ga_accounts' );
158
- delete_option( 'yst_ga_response' );
 
 
 
 
159
 
160
- }
 
 
161
 
162
- /**
163
- * Are we allowed to show a warning message? returns true if it's allowed
164
- *
165
- * @return bool
166
- */
167
- private function show_admin_warning() {
168
- if ( current_user_can( 'manage_options' ) ) {
169
- if ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) {
170
- return true;
171
- }
172
- }
173
 
174
- return false;
175
- }
 
 
 
 
 
 
176
 
177
- /**
178
- * Are we allowed to show a warning message? returns true if it's allowed ( this is meant to be only for dashboard )
179
- *
180
- * @return bool
181
- */
182
- private function show_admin_dashboard_warning() {
183
- return ( current_user_can( 'manage_options' ) && isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' );
184
- }
185
 
186
- /**
187
- * Transform the Profile ID into an helpful UA code
188
- *
189
- * @param $profile_id
190
- *
191
- * @return null
192
- */
193
- private function get_ua_code_from_profile( $profile_id ) {
194
- $profiles = $this->get_profiles();
195
- $ua_code = null;
196
-
197
- foreach ( $profiles as $account ) {
198
- foreach ( $account['items'] as $profile ) {
199
- foreach ( $profile['items'] as $subprofile ) {
200
- if ( isset( $subprofile['id'] ) && $subprofile['id'] === $profile_id ) {
201
- return $subprofile['ua_code'];
202
- }
203
  }
204
  }
205
  }
206
-
207
- return $ua_code;
208
  }
209
 
210
- /**
211
- * Add a link to the settings page to the plugins list
212
- *
213
- * @param array $links array of links for the plugins, adapted when the current plugin is found.
214
- *
215
- * @return array $links
216
- */
217
- public function add_action_links( $links ) {
218
- // add link to knowledgebase
219
- // @todo UTM link fix
220
- $faq_link = '<a title="Yoast Knowledge Base" href="http://kb.yoast.com/category/43-google-analytics-for-wordpress">' . __( 'FAQ', 'google-analytics-for-wordpress' ) . '</a>';
221
- array_unshift( $links, $faq_link );
222
-
223
- $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=yst_ga_settings' ) ) . '">' . __( 'Settings', 'google-analytics-for-wordpress' ) . '</a>';
224
- array_unshift( $links, $settings_link );
225
-
226
- return $links;
227
- }
228
 
229
- /**
230
- * Adds some promo text for the premium plugin on the custom dimensions tab.
231
- */
232
- public function premium_promo() {
233
- echo '<div class="ga-promote">';
234
- echo '<p>';
235
- printf( __( 'If you want to track custom dimensions, to for instance track page views per author or post type, you should upgrade to the %1$spremium version of Google Analytics by Yoast%2$s.', 'google-analytics-for-wordpress' ), '<a href="https://yoast.com/wordpress/plugins/google-analytics/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin&utm_content=custom_dimensions_tab">', '</a>' );
236
- echo ' ';
237
- _e( 'This will also give you email access to the support team at Yoast, who will provide support on the plugin 24/7.', 'google-analytics-for-wordpress' );
238
- echo '</p>';
239
- echo '</div>';
240
- }
 
 
 
 
 
 
241
 
242
- /**
243
- * Initialize the promo class for our translate site
244
- *
245
- * @return yoast_i18n
246
- */
247
- public function translate_promo() {
248
- $yoast_ga_i18n = new yoast_i18n(
249
- array(
250
- 'textdomain' => 'google-analytics-for-wordpress',
251
- 'project_slug' => 'google-analytics-for-wordpress',
252
- 'plugin_name' => 'Google Analytics by Yoast',
253
- 'hook' => 'yoast_ga_admin_footer',
254
- 'glotpress_url' => 'http://translate.yoast.com',
255
- 'glotpress_name' => 'Yoast Translate',
256
- 'glotpress_logo' => 'https://cdn.yoast.com/wp-content/uploads/i18n-images/Yoast_Translate.svg',
257
- 'register_url ' => 'http://translate.yoast.com/projects#utm_source=plugin&utm_medium=promo-box&utm_campaign=yoast-ga-i18n-promo',
258
- )
259
- );
260
 
261
- return $yoast_ga_i18n;
262
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
263
 
264
- /**
265
- * Load the page of a menu item in the GA plugin
266
- */
267
- public function load_page() {
268
 
269
- $this->translate_promo();
270
 
271
- if ( ! has_action( 'yst_ga_custom_dimensions_tab-content' ) ) {
272
- add_action( 'yst_ga_custom_dimensions_tab-content', array( $this, 'premium_promo' ) );
273
- }
274
 
275
- if ( ! has_action( 'yst_ga_custom_dimension_add-dashboards-tab' ) ) {
276
- add_action( 'yst_ga_custom_dimension_add-dashboards-tab', array( $this, 'premium_promo' ) );
277
- }
278
 
279
- if ( isset( $_GET['page'] ) ) {
280
- switch ( $_GET['page'] ) {
281
- case 'yst_ga_settings':
282
- require_once( $this->plugin_path . 'admin/pages/settings.php' );
283
- break;
284
- case 'yst_ga_extensions':
285
- require_once( $this->plugin_path . 'admin/pages/extensions.php' );
286
- break;
287
- case 'yst_ga_dashboard':
288
- default:
289
- require_once( $this->plugin_path . 'admin/pages/dashboard.php' );
290
- break;
291
- }
292
  }
293
  }
 
294
 
295
 
296
- /**
297
- * Get the Google Analytics profiles which are in this google account
298
- *
299
- * @return array
300
- */
301
- public function get_profiles() {
302
- $return = Yoast_Google_Analytics::get_instance()->get_profiles();
303
-
304
- return $return;
305
- }
306
-
307
- /**
308
- * Checks if there is a callback or reauth to get token from Google Analytics api
309
- */
310
- private function google_analytics_listener() {
311
 
312
- if ( ! empty( $_POST['google_auth_code'] ) ) {
313
- Yoast_Google_Analytics::get_instance()->authenticate( trim( $_POST['google_auth_code'] ) );
314
- }
315
 
 
 
 
 
316
 
317
- if ( ! empty ( $_GET['reauth'] ) ) {
 
 
318
 
319
- delete_option( 'yst_ga_accounts' );
320
- delete_option( 'yst_ga_response' );
321
 
322
- Yoast_Google_Analytics::get_instance()->authenticate();
323
- }
324
 
325
- }
 
326
 
327
- /**
328
- * Get the current GA profile
329
- *
330
- * @return null
331
- */
332
- private function get_current_profile() {
333
- if ( ! empty( $this->options['analytics_profile'] ) ) {
334
- return $this->options['analytics_profile'];
335
- } else {
336
- return null;
337
- }
338
  }
339
 
340
- /**
341
- * Get the user roles of this WordPress blog
342
- *
343
- * @return array
344
- */
345
- public function get_userroles() {
346
- global $wp_roles;
347
-
348
- $all_roles = $wp_roles->roles;
349
- $roles = array();
350
-
351
- /**
352
- * Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
353
- *
354
- * @api array $all_roles
355
- */
356
- $editable_roles = apply_filters( 'editable_roles', $all_roles );
357
- foreach ( $editable_roles as $id => $name ) {
358
- $roles[] = array(
359
- 'id' => $id,
360
- 'name' => $name['name'],
361
- );
362
- }
363
 
364
- return $roles;
 
 
 
 
 
 
 
 
 
365
  }
 
366
 
367
- /**
368
- * Get types of how we can track downloads
369
- *
370
- * @return array
371
- */
372
- public function track_download_types() {
373
- return array(
374
- 0 => array( 'id' => 'event', 'name' => 'Event' ),
375
- 1 => array( 'id' => 'pageview', 'name' => 'Pageview' ),
376
- );
377
- }
378
 
379
  /**
380
- * Get options for the track full url or links setting
381
  *
382
- * @return array
383
  */
384
- public function get_track_full_url() {
385
- return array(
386
- 0 => array( 'id' => 'domain', 'name' => 'Just the domain' ),
387
- 1 => array( 'id' => 'full_links', 'name' => 'Full links' ),
 
388
  );
389
  }
390
 
391
- /**
392
- * Render the admin page head for the GA Plugin
393
- */
394
- public function content_head() {
395
- require 'views/content_head.php';
396
- }
397
-
398
- /**
399
- * Render the admin page footer with sidebar for the GA Plugin
400
- */
401
- public function content_footer() {
402
-
403
- do_action( 'yoast_ga_admin_footer' );
404
 
405
- if ( true == WP_DEBUG ) {
406
- // Show the debug information if debug is enabled in the wp_config file
407
- echo '<div id="ga-debug-info" class="postbox"><h3 class="hndle"><span>' . __( 'Debug information', 'google-analytics-for-wordpress' ) . '</span></h3><div class="inside"><pre>';
408
- var_dump( $this->options );
409
- echo '</pre></div></div>';
410
- }
 
 
 
 
 
411
 
412
- if ( class_exists( 'Yoast_Product_GA_Premium' ) ) {
413
- $license_manager = new Yoast_Plugin_License_Manager( new Yoast_Product_GA_Premium() );
414
- if ( $license_manager->license_is_valid() ) {
415
- return;
416
- }
417
- }
 
 
 
 
 
418
 
419
- $banners = array();
420
- $banners[] = array(
421
- 'url' => 'https://yoast.com/hire-us/website-review/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
422
- 'banner' => $this->plugin_url . 'assets/img/banner-website-review.png',
423
- 'title' => 'Get a website review by Yoast',
424
- );
425
- $banners[] = array(
426
- 'url' => 'https://yoast.com/wordpress/plugins/google-analytics/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
427
- 'banner' => $this->plugin_url . 'assets/img/banner-premium-ga.png',
428
- 'title' => 'Get the premium version of Google Analytics by Yoast!',
429
- );
430
- $banners[] = array(
431
- 'url' => 'https://yoast.com/ebook-optimize-wordpress-site/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
432
- 'banner' => $this->plugin_url . 'assets/img/eBook_261x130.png',
433
- 'title' => 'Get the Yoast ebook!',
434
- );
435
- $banners[] = array(
436
- 'url' => 'https://yoast.com/wordpress/plugins/ga-ecommerce/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
437
- 'banner' => $this->plugin_url . 'assets/img/banner-ga-ecommerce.png',
438
- 'title' => 'Get advanced eCommerce tracking for WooCommerce and Easy Digital Downloads!',
439
- );
440
 
441
- shuffle( $banners );
 
 
 
442
 
443
- require 'views/content-footer.php';
444
 
 
 
 
 
 
445
  }
446
 
447
- /**
448
- * Returns a list of all available extensions
449
- *
450
- * @return array
451
- */
452
- public function get_extensions() {
453
- $extensions = array(
454
- 'ga_premium' => (object) array(
455
- 'url' => 'https://yoast.com/wordpress/plugins/google-analytics/',
456
- 'title' => __( 'Google Analytics by Yoast Premium', 'google-analytics-for-wordpress' ),
457
- 'desc' => __( 'The premium version of Google Analytics for WordPress with more features &amp; support.', 'google-analytics-for-wordpress' ),
458
- 'status' => 'uninstalled',
459
- ),
460
- 'ecommerce' => (object) array(
461
- 'url' => 'https://yoast.com/wordpress/plugins/ga-ecommerce/',
462
- 'title' => __( 'Google Analytics', 'google-analytics-for-wordpress' ) . '<br />' . __( 'E-Commerce tracking', 'google-analytics-for-wordpress' ),
463
- 'desc' => __( 'Track your E-Commerce data and transactions with this E-Commerce extension for Google Analytics.', 'google-analytics-for-wordpress' ),
464
- 'status' => 'uninstalled',
465
- ),
466
- );
467
 
468
- $extensions = apply_filters( 'yst_ga_extension_status', $extensions );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
 
470
- return $extensions;
471
- }
472
 
473
- /**
474
- * Add a notification to the notification transient
475
- *
476
- * @param $transient_name
477
- * @param $settings
478
- */
479
- private function add_notification( $transient_name, $settings ) {
480
- set_transient( $transient_name, $settings, MINUTE_IN_SECONDS );
481
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
482
 
483
- /**
484
- * Show the notification that should be set, after showing the notification this function unset the transient
485
- *
486
- * @param string $transient_name The name of the transient which contains the notification
487
- */
488
- public function show_notification( $transient_name ) {
489
- $transient = get_transient( $transient_name );
490
-
491
- if ( isset( $transient['type'] ) && isset( $transient['description'] ) ) {
492
- if ( $transient['type'] == 'success' ) {
493
- add_settings_error(
494
- 'yoast_google_analytics',
495
- 'yoast_google_analytics',
496
- $transient['description'],
497
- 'updated'
498
- );
499
- } else {
500
- add_settings_error(
501
- 'yoast_google_analytics',
502
- 'yoast_google_analytics',
503
- $transient['description'],
504
- 'error'
505
- );
506
- }
507
 
508
- delete_transient( $transient_name );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
509
  }
510
- }
511
 
 
 
512
  }
513
 
514
- }
1
  <?php
2
+
3
  /**
4
  * This class is for the backend, extendable for all child classes
5
  */
6
+ class Yoast_GA_Admin extends Yoast_GA_Options {
7
 
8
+ /**
9
+ * Store the API instance
10
+ *
11
+ * @var
12
+ */
13
+ public $api;
 
 
 
 
14
 
15
+ public function __construct() {
16
+ parent::__construct();
17
 
18
+ add_action( 'plugins_loaded', array( $this, 'init_ga' ) );
19
+ add_action( 'admin_init', array( $this, 'init_settings' ) );
20
+ }
21
 
22
+ /**
23
+ * Init function when the plugin is loaded
24
+ */
25
+ public function init_ga() {
26
 
27
+ new Yoast_GA_Admin_Menu( $this );
28
 
29
+ add_filter( 'plugin_action_links_' . plugin_basename( GAWP_FILE ), array( $this, 'add_action_links' ) );
30
 
31
+ }
32
 
33
+ /**
34
+ * Init function for the settings of GA
35
+ */
36
+ public function init_settings() {
37
+ $this->options = $this->get_options();
38
+ $this->api = Yoast_Api_Libs::load_api_libraries( array( 'google', 'googleanalytics' ) );
39
+ $dashboards = Yoast_GA_Dashboards::get_instance();
40
 
41
+ // Listener for reconnecting with google analytics
42
+ $this->google_analytics_listener();
43
 
44
+ if ( is_null( $this->get_tracking_code() ) && $this->show_admin_warning() ) {
45
+ add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', 'config_warning' ) );
46
+ }
47
 
48
+ // Check if something has went wrong with GA-api calls
49
+ $has_tracking_code = ( ! is_null( $this->get_tracking_code() ) && empty( $this->options['manual_ua_code_field'] ) );
50
+ if ( $has_tracking_code && $this->show_admin_dashboard_warning() ) {
51
+ Yoast_Google_Analytics::get_instance()->check_for_ga_issues();
52
+ }
53
 
54
+ if ( $_SERVER['REQUEST_METHOD'] == 'POST' ) {
55
+ if ( ! function_exists( 'wp_verify_nonce' ) ) {
56
+ require_once( ABSPATH . 'wp-includes/pluggable.php' );
 
 
 
57
  }
58
 
59
+ if ( isset( $_POST['ga-form-settings'] ) && wp_verify_nonce( $_POST['yoast_ga_nonce'], 'save_settings' ) ) {
60
+ if ( ! isset ( $_POST['ignore_users'] ) ) {
61
+ $_POST['ignore_users'] = array();
62
  }
63
 
64
+ $dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
 
 
 
65
 
66
+ if ( $dashboards_disabled == false && isset( $_POST['dashboards_disabled'] ) ) {
67
+ $dashboards->reset_dashboards_data();
68
  }
 
 
 
 
 
 
69
 
70
+ // Post submitted and verified with our nonce
71
+ $this->save_settings( $_POST );
72
+ }
 
 
 
 
 
 
 
73
  }
74
 
75
  /**
76
+ * Show the notifications if we have one
77
  */
78
+ $this->show_notification( 'ga_notifications' );
 
 
79
 
80
+ // Load the Google Analytics Dashboards functionality
81
+ $dashboards->init_dashboards( $this->get_current_profile() );
82
+ }
 
 
 
83
 
84
+ /**
85
+ * This function saves the settings in the option field and returns a wp success message on success
86
+ *
87
+ * @param $data
88
+ */
89
+ public function save_settings( $data ) {
90
 
91
+ unset( $data['google_auth_code'] );
 
 
 
 
 
 
 
92
 
93
+ foreach ( $data as $key => $value ) {
94
+ if ( $key != 'return_tab' ) {
95
+ if ( $key != 'custom_code' && is_string( $value ) ) {
96
+ $value = strip_tags( $value );
 
 
97
  }
98
+ $this->options[$key] = $value;
99
  }
100
+ }
101
 
102
+ // Check checkboxes, on a uncheck they won't be posted to this function
103
+ $defaults = $this->default_ga_values();
104
+ foreach ( $defaults[$this->option_prefix] as $key => $value ) {
105
+ if ( ! isset( $data[$key] ) ) {
106
+ // If no data was passed in, set it to the default.
107
+ $this->options[$key] = $value;
108
  }
109
+ }
110
 
111
+ if ( ! empty( $this->options['analytics_profile'] ) ) {
112
+ $this->options['analytics_profile_code'] = $this->get_ua_code_from_profile( $this->options['analytics_profile'] );
113
+ }
 
 
 
 
 
 
 
 
 
 
 
114
 
115
+ if ( $this->update_option( $this->options ) ) {
116
+ // Success, add a new notification
117
+ $this->add_notification( 'ga_notifications', array(
118
+ 'type' => 'success',
119
+ 'description' => __( 'Settings saved.', 'google-analytics-for-wordpress' ),
120
+ ) );
121
+
122
+ } else {
123
+ // Fail, add a new notification
124
+ $this->add_notification( 'ga_notifications', array(
125
+ 'type' => 'error',
126
+ 'description' => __( 'There were no changes to save, please try again.', 'google-analytics-for-wordpress' ),
127
+ ) );
128
  }
129
 
130
+ #redirect
131
+ wp_redirect( admin_url( 'admin.php' ) . '?page=yst_ga_settings#top#' . $data['return_tab'], 301 );
132
+ exit;
133
+ }
 
 
 
134
 
135
+ /**
136
+ * Run a this deactivation hook on deactivation of GA. When this happens we'll
137
+ * remove the options for the profiles and the refresh token.
138
+ */
139
+ public static function ga_deactivation_hook() {
140
+ // Remove the refresh token
141
+ delete_option( 'yoast-ga-refresh_token' );
142
 
143
+ // Remove the ga accounts and response
144
+ delete_option( 'yst_ga_accounts' );
145
+ delete_option( 'yst_ga_response' );
146
 
147
+ }
 
 
 
 
 
 
 
 
 
 
148
 
149
+ /**
150
+ * Are we allowed to show a warning message? returns true if it's allowed
151
+ *
152
+ * @return bool
153
+ */
154
+ private function show_admin_warning() {
155
+ return ( current_user_can( 'manage_options' ) && ( ! isset( $_GET['page'] ) || ( isset( $_GET['page'] ) && $_GET['page'] !== 'yst_ga_settings' ) ) );
156
+ }
157
 
158
+ /**
159
+ * Are we allowed to show a warning message? returns true if it's allowed ( this is meant to be only for dashboard )
160
+ *
161
+ * @return bool
162
+ */
163
+ private function show_admin_dashboard_warning() {
164
+ return ( current_user_can( 'manage_options' ) && isset( $_GET['page'] ) && $_GET['page'] === 'yst_ga_dashboard' );
165
+ }
166
 
167
+ /**
168
+ * Transform the Profile ID into an helpful UA code
169
+ *
170
+ * @param $profile_id
171
+ *
172
+ * @return null
173
+ */
174
+ private function get_ua_code_from_profile( $profile_id ) {
175
+ $profiles = $this->get_profiles();
176
+ $ua_code = null;
177
+
178
+ foreach ( $profiles as $account ) {
179
+ foreach ( $account['items'] as $profile ) {
180
+ foreach ( $profile['items'] as $subprofile ) {
181
+ if ( isset( $subprofile['id'] ) && $subprofile['id'] === $profile_id ) {
182
+ return $subprofile['ua_code'];
 
183
  }
184
  }
185
  }
 
 
186
  }
187
 
188
+ return $ua_code;
189
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
 
191
+ /**
192
+ * Add a link to the settings page to the plugins list
193
+ *
194
+ * @param array $links array of links for the plugins, adapted when the current plugin is found.
195
+ *
196
+ * @return array $links
197
+ */
198
+ public function add_action_links( $links ) {
199
+ // add link to knowledgebase
200
+ // @todo UTM link fix
201
+ $faq_link = '<a title="Yoast Knowledge Base" href="http://kb.yoast.com/category/43-google-analytics-for-wordpress">' . __( 'FAQ', 'google-analytics-for-wordpress' ) . '</a>';
202
+ array_unshift( $links, $faq_link );
203
+
204
+ $settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=yst_ga_settings' ) ) . '">' . __( 'Settings', 'google-analytics-for-wordpress' ) . '</a>';
205
+ array_unshift( $links, $settings_link );
206
+
207
+ return $links;
208
+ }
209
 
210
+ /**
211
+ * Adds some promo text for the premium plugin on the custom dimensions tab.
212
+ */
213
+ public function premium_promo() {
214
+ echo '<div class="ga-promote">';
215
+ echo '<p>';
216
+ printf( __( 'If you want to track custom dimensions like page views per author or post type, you should upgrade to the %1$spremium version of Google Analytics by Yoast%2$s.', 'google-analytics-for-wordpress' ), '<a href="https://yoast.com/wordpress/plugins/google-analytics/#utm_medium=text-link&utm_source=gawp-config&utm_campaign=wpgaplugin&utm_content=custom_dimensions_tab">', '</a>' );
217
+ echo ' ';
218
+ _e( 'This will also give you email access to the support team at Yoast, who will provide support on the plugin 24/7.', 'google-analytics-for-wordpress' );
219
+ echo '</p>';
220
+ echo '</div>';
221
+ }
 
 
 
 
 
 
222
 
223
+ /**
224
+ * Initialize the promo class for our translate site
225
+ *
226
+ * @return yoast_i18n
227
+ */
228
+ public function translate_promo() {
229
+ $yoast_ga_i18n = new yoast_i18n(
230
+ array(
231
+ 'textdomain' => 'google-analytics-for-wordpress',
232
+ 'project_slug' => 'google-analytics-for-wordpress',
233
+ 'plugin_name' => 'Google Analytics by Yoast',
234
+ 'hook' => 'yoast_ga_admin_footer',
235
+ 'glotpress_url' => 'http://translate.yoast.com',
236
+ 'glotpress_name' => 'Yoast Translate',
237
+ 'glotpress_logo' => 'https://cdn.yoast.com/wp-content/uploads/i18n-images/Yoast_Translate.svg',
238
+ 'register_url ' => 'http://translate.yoast.com/projects#utm_source=plugin&utm_medium=promo-box&utm_campaign=yoast-ga-i18n-promo',
239
+ )
240
+ );
241
+
242
+ return $yoast_ga_i18n;
243
+ }
244
 
245
+ /**
246
+ * Load the page of a menu item in the GA plugin
247
+ */
248
+ public function load_page() {
249
 
250
+ $this->translate_promo();
251
 
252
+ if ( ! has_action( 'yst_ga_custom_dimensions_tab-content' ) ) {
253
+ add_action( 'yst_ga_custom_dimensions_tab-content', array( $this, 'premium_promo' ) );
254
+ }
255
 
256
+ if ( ! has_action( 'yst_ga_custom_dimension_add-dashboards-tab' ) ) {
257
+ add_action( 'yst_ga_custom_dimension_add-dashboards-tab', array( $this, 'premium_promo' ) );
258
+ }
259
 
260
+ if ( isset( $_GET['page'] ) ) {
261
+ switch ( $_GET['page'] ) {
262
+ case 'yst_ga_settings':
263
+ require_once( $this->plugin_path . 'admin/pages/settings.php' );
264
+ break;
265
+ case 'yst_ga_extensions':
266
+ require_once( $this->plugin_path . 'admin/pages/extensions.php' );
267
+ break;
268
+ case 'yst_ga_dashboard':
269
+ default:
270
+ require_once( $this->plugin_path . 'admin/pages/dashboard.php' );
271
+ break;
 
272
  }
273
  }
274
+ }
275
 
276
 
277
+ /**
278
+ * Get the Google Analytics profiles which are in this google account
279
+ *
280
+ * @return array
281
+ */
282
+ public function get_profiles() {
283
+ $return = Yoast_Google_Analytics::get_instance()->get_profiles();
 
 
 
 
 
 
 
 
284
 
285
+ return $return;
286
+ }
 
287
 
288
+ /**
289
+ * Checks if there is a callback or reauth to get token from Google Analytics api
290
+ */
291
+ private function google_analytics_listener() {
292
 
293
+ if ( ! empty( $_POST['google_auth_code'] ) ) {
294
+ Yoast_Google_Analytics::get_instance()->authenticate( trim( $_POST['google_auth_code'] ) );
295
+ }
296
 
 
 
297
 
298
+ if ( ! empty ( $_GET['reauth'] ) ) {
 
299
 
300
+ delete_option( 'yst_ga_accounts' );
301
+ delete_option( 'yst_ga_response' );
302
 
303
+ Yoast_Google_Analytics::get_instance()->authenticate();
 
 
 
 
 
 
 
 
 
 
304
  }
305
 
306
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
307
 
308
+ /**
309
+ * Get the current GA profile
310
+ *
311
+ * @return null
312
+ */
313
+ private function get_current_profile() {
314
+ if ( ! empty( $this->options['analytics_profile'] ) ) {
315
+ return $this->options['analytics_profile'];
316
+ } else {
317
+ return null;
318
  }
319
+ }
320
 
321
+ /**
322
+ * Get the user roles of this WordPress blog
323
+ *
324
+ * @return array
325
+ */
326
+ public function get_userroles() {
327
+ global $wp_roles;
328
+
329
+ $all_roles = $wp_roles->roles;
330
+ $roles = array();
 
331
 
332
  /**
333
+ * Filter: 'editable_roles' - Allows filtering of the roles shown within the plugin (and elsewhere in WP as it's a WP filter)
334
  *
335
+ * @api array $all_roles
336
  */
337
+ $editable_roles = apply_filters( 'editable_roles', $all_roles );
338
+ foreach ( $editable_roles as $id => $name ) {
339
+ $roles[] = array(
340
+ 'id' => $id,
341
+ 'name' => $name['name'],
342
  );
343
  }
344
 
345
+ return $roles;
346
+ }
 
 
 
 
 
 
 
 
 
 
 
347
 
348
+ /**
349
+ * Get types of how we can track downloads
350
+ *
351
+ * @return array
352
+ */
353
+ public function track_download_types() {
354
+ return array(
355
+ 0 => array( 'id' => 'event', 'name' => 'Event' ),
356
+ 1 => array( 'id' => 'pageview', 'name' => 'Pageview' ),
357
+ );
358
+ }
359
 
360
+ /**
361
+ * Get options for the track full url or links setting
362
+ *
363
+ * @return array
364
+ */
365
+ public function get_track_full_url() {
366
+ return array(
367
+ 0 => array( 'id' => 'domain', 'name' => 'Just the domain' ),
368
+ 1 => array( 'id' => 'full_links', 'name' => 'Full links' ),
369
+ );
370
+ }
371
 
372
+ /**
373
+ * Render the admin page head for the GA Plugin
374
+ */
375
+ public function content_head() {
376
+ require 'views/content_head.php';
377
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
 
379
+ /**
380
+ * Render the admin page footer with sidebar for the GA Plugin
381
+ */
382
+ public function content_footer() {
383
 
384
+ do_action( 'yoast_ga_admin_footer' );
385
 
386
+ if ( true == WP_DEBUG ) {
387
+ // Show the debug information if debug is enabled in the wp_config file
388
+ echo '<div id="ga-debug-info" class="postbox"><h3 class="hndle"><span>' . __( 'Debug information', 'google-analytics-for-wordpress' ) . '</span></h3><div class="inside"><pre>';
389
+ var_dump( $this->options );
390
+ echo '</pre></div></div>';
391
  }
392
 
393
+ if ( class_exists( 'Yoast_Product_GA_Premium' ) ) {
394
+ $license_manager = new Yoast_Plugin_License_Manager( new Yoast_Product_GA_Premium() );
395
+ if ( $license_manager->license_is_valid() ) {
396
+ return;
397
+ }
398
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
 
400
+ $banners = array();
401
+ $banners[] = array(
402
+ 'url' => 'https://yoast.com/hire-us/website-review/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
403
+ 'banner' => $this->plugin_url . 'assets/img/banner-website-review.png',
404
+ 'title' => 'Get a website review by Yoast',
405
+ );
406
+ $banners[] = array(
407
+ 'url' => 'https://yoast.com/wordpress/plugins/google-analytics/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
408
+ 'banner' => $this->plugin_url . 'assets/img/banner-premium-ga.png',
409
+ 'title' => 'Get the premium version of Google Analytics by Yoast!',
410
+ );
411
+ $banners[] = array(
412
+ 'url' => 'https://yoast.com/ebook-optimize-wordpress-site/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
413
+ 'banner' => $this->plugin_url . 'assets/img/eBook_261x130.png',
414
+ 'title' => 'Get the Yoast ebook!',
415
+ );
416
+ $banners[] = array(
417
+ 'url' => 'https://yoast.com/wordpress/plugins/ga-ecommerce/#utm_medium=banner&utm_source=gawp-config&utm_campaign=wpgaplugin',
418
+ 'banner' => $this->plugin_url . 'assets/img/banner-ga-ecommerce.png',
419
+ 'title' => 'Get advanced eCommerce tracking for WooCommerce and Easy Digital Downloads!',
420
+ );
421
+
422
+ shuffle( $banners );
423
+
424
+ require 'views/content-footer.php';
425
 
426
+ }
 
427
 
428
+ /**
429
+ * Returns a list of all available extensions
430
+ *
431
+ * @return array
432
+ */
433
+ public function get_extensions() {
434
+ $extensions = array(
435
+ 'ga_premium' => (object) array(
436
+ 'url' => 'https://yoast.com/wordpress/plugins/google-analytics/',
437
+ 'title' => __( 'Google Analytics by Yoast Premium', 'google-analytics-for-wordpress' ),
438
+ 'desc' => __( 'The premium version of Google Analytics by Yoast with more features and support.', 'google-analytics-for-wordpress' ),
439
+ 'status' => 'uninstalled',
440
+ ),
441
+ 'ecommerce' => (object) array(
442
+ 'url' => 'https://yoast.com/wordpress/plugins/ga-ecommerce/',
443
+ 'title' => __( 'Google Analytics by Yoast', 'google-analytics-for-wordpress' ) . '<br />' . __( 'eCommerce tracking', 'google-analytics-for-wordpress' ),
444
+ 'desc' => __( 'Track your eCommerce data and transactions with this eCommerce extension for Google Analytics.', 'google-analytics-for-wordpress' ),
445
+ 'status' => 'uninstalled',
446
+ ),
447
+ );
448
+
449
+ $extensions = apply_filters( 'yst_ga_extension_status', $extensions );
450
+
451
+ return $extensions;
452
+ }
453
 
454
+ /**
455
+ * Add a notification to the notification transient
456
+ *
457
+ * @param $transient_name
458
+ * @param $settings
459
+ */
460
+ private function add_notification( $transient_name, $settings ) {
461
+ set_transient( $transient_name, $settings, MINUTE_IN_SECONDS );
462
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
 
464
+ /**
465
+ * Show the notification that should be set, after showing the notification this function unset the transient
466
+ *
467
+ * @param string $transient_name The name of the transient which contains the notification
468
+ */
469
+ public function show_notification( $transient_name ) {
470
+ $transient = get_transient( $transient_name );
471
+
472
+ if ( isset( $transient['type'] ) && isset( $transient['description'] ) ) {
473
+ if ( $transient['type'] == 'success' ) {
474
+ add_settings_error(
475
+ 'yoast_google_analytics',
476
+ 'yoast_google_analytics',
477
+ $transient['description'],
478
+ 'updated'
479
+ );
480
+ } else {
481
+ add_settings_error(
482
+ 'yoast_google_analytics',
483
+ 'yoast_google_analytics',
484
+ $transient['description'],
485
+ 'error'
486
+ );
487
  }
 
488
 
489
+ delete_transient( $transient_name );
490
+ }
491
  }
492
 
493
+ }
admin/class-google-analytics.php CHANGED
@@ -1,272 +1,353 @@
1
  <?php
2
 
3
 
4
- if ( ! class_exists( 'Yoast_Google_Analytics', false ) ) {
5
-
6
- class Yoast_Google_Analytics {
7
-
8
- /**
9
- * @var string
10
- */
11
- private $option_name = 'yst_ga_api';
12
-
13
- /**
14
- * @var array|mixed
15
- */
16
- private $options = array();
17
-
18
- /**
19
- * @var null|Yoast_Google_Analytics
20
- */
21
- private static $instance = null;
22
-
23
- /**
24
- * @var The api client object holder
25
- */
26
- private $client;
27
-
28
- /**
29
- * Singleton
30
- *
31
- */
32
- protected function __construct() {
33
-
34
- if ( is_null( self::$instance ) ) {
35
- self::$instance = $this;
36
- }
37
 
38
- $this->options = $this->get_options();
 
 
 
 
39
 
40
- // Setting the client
41
- $this->set_client();
 
 
 
 
 
 
 
 
 
42
  }
43
 
44
- /**
45
- * Getting the instance object
46
- *
47
- * This method will return the instance of itself, if instance not exists, becauses of it's called for the first
48
- * time, the instance will be created.
49
- *
50
- * @return null|Yoast_Google_Analytics
51
- */
52
- public static function get_instance() {
53
- if ( is_null( self::$instance ) ) {
54
- self::$instance = new self();
55
- }
56
 
57
- return self::$instance;
58
- }
59
 
60
- /**
61
- * Wrapper for authenticate the client. If authentication code is send it will get and check an access token.
62
- *
63
- * @param mixed $authentication_code
64
- */
65
- public function authenticate( $authentication_code = null ) {
66
- $this->client->authenticate_client( $authentication_code );
67
- }
68
 
69
- /**
70
- * Getting the analytics profiles
71
- *
72
- * Doing the request to the Google analytics API and if there is a response, parses this response and return its
73
- * array
74
- *
75
- * @return array
76
- */
77
- public function get_profiles() {
78
- $accounts = $this->format_profile_call(
79
- $this->do_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' )
80
- );
81
 
82
- if ( is_array( $accounts ) ) {
83
- $this->save_profile_response( $accounts );
 
84
 
85
- return $accounts;
 
 
86
  }
87
 
88
- return array();
89
  }
90
 
91
- /**
92
- * Doing request to Google Analytics
93
- *
94
- * This method will do a request to google and get the response code and body from content
95
- *
96
- * @param string $target_request_url
97
- *
98
- * @return array|null
99
- */
100
- public function do_request( $target_request_url ) {
101
-
102
- $response = $this->client->do_request( $target_request_url );
103
-
104
- if ( ! empty( $response ) ) {
105
- return array(
106
- 'response' => array( 'code' => $this->client->get_http_response_code() ),
107
- 'body' => json_decode( $response->getResponseBody(), true ),
108
- );
109
- }
110
 
111
- }
 
 
 
 
 
 
 
112
 
 
 
113
 
114
- /**
115
- * Check if client has a refresh token
116
- * @return bool
117
- */
118
- public function has_refresh_token() {
119
- return ( $this->client->get_refresh_token() != '' );
 
 
 
 
 
 
 
 
 
 
 
120
  }
121
 
122
- /**
123
- * Getting the options bases on $this->option_name from the database
124
- *
125
- * @return mixed
126
- */
127
- public function get_options() {
128
- return get_option( $this->option_name );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
- /**
132
- * Checks whether we'll ever be able to reach Google.
133
- *
134
- * @return bool
135
- */
136
- public function check_google_access_from_wp() {
137
- $can_access_google = true;
138
- if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
139
- $can_access_google = false;
140
- if ( defined( 'WP_ACCESSIBLE_HOSTS' ) ) {
141
- // Better to use the internal WP logic from this point forward.
142
- $can_access_google = $this->test_connection_to_google();
143
- }
144
- }
145
 
146
- return $can_access_google;
147
- }
148
 
149
- /**
150
- * Check if we can access Google Apis from this server by making a dummy connection
151
- */
152
- public function check_google_access() {
153
- return $this->test_connection_to_google();
154
- }
 
155
 
156
- /**
157
- * Updating the options based on $this->option_name and the internal property $this->options
158
- */
159
- protected function update_options() {
160
- update_option( $this->option_name, $this->options );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
  }
162
 
163
- /**
164
- * Setting the client
165
- *
166
- * The filter is a hook to override the configuration/
167
- */
168
- protected function set_client() {
169
- $config = array(
170
- 'application_name' => 'Google Analytics by Yoast',
171
- 'client_id' => '346753076522-21smrc6aq0hq8oij8001s57dfoo8igf5.apps.googleusercontent.com',
172
- 'client_secret' => '5oWaEGFgp-bSrY6vWBmdPfIF',
173
- );
174
 
175
- $config = apply_filters( 'yst-ga-filter-ga-config', $config );
 
 
 
 
 
176
 
177
- $this->client = new Yoast_Google_Analytics_Client( $config );
178
- }
 
 
 
 
179
 
180
- /**
181
- * Gets an authentication URL
182
- *
183
- * @return mixed
184
- */
185
- public function create_auth_url() {
186
- return $this->client->createAuthUrl();
187
- }
 
 
 
 
 
 
 
 
188
 
189
- /**
190
- * Saving profile response in options
191
- *
192
- * @param array $accounts
193
- */
194
- protected function save_profile_response( $accounts ) {
195
- $this->options['ga_api_response_accounts'] = $accounts;
 
196
 
197
- $this->update_options();
198
- }
 
 
 
 
 
199
 
200
- /**
201
- * Test a connection to Google
202
- *
203
- * @return bool
204
- */
205
- private function test_connection_to_google(){
206
- $wp_http = new WP_Http();
207
- if ( $wp_http->block_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' ) === false ) {
208
- return true;
209
- }
210
 
211
- return false;
 
 
 
 
 
 
 
 
212
  }
213
 
214
- /**
215
- * Format the accounts request
216
- *
217
- * @param $response
218
- *
219
- * @return mixed
220
- */
221
- private function format_profile_call( $response ) {
222
-
223
- if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
224
- if ( ! empty( $response['body']['items'] ) && is_array( $response['body']['items'] ) ) {
225
- $accounts = array();
226
-
227
- foreach ( $response['body']['items'] as $item ) {
228
- // Check if webProperties is set
229
- if ( isset( $item['webProperties'] ) ) {
230
- $profiles = array();
231
-
232
- foreach ( $item['webProperties'] as $property_key => $property ) {
233
- $profiles[$property_key] = array(
234
- 'id' => $property['id'],
235
- 'name' => $property['name'],
236
- 'items' => array(),
237
- );
238
-
239
- // Check if profiles is set
240
- if ( isset( $property['profiles'] ) ) {
241
- foreach ( $property['profiles'] as $key => $profile ) {
242
- $profiles[$property_key]['items'][$key] = array_merge(
243
- $profile,
244
- array(
245
- 'name' => $profile['name'] . ' (' . $property['id'] . ')',
246
- 'ua_code' => $property['id'],
247
- )
248
- );
249
- }
250
- }
251
- }
252
 
253
- $accounts[$item['id']] = array(
254
- 'id' => $item['id'],
255
- 'ua_code' => $property['id'],
256
- 'parent_name' => $item['name'],
257
- 'items' => $profiles,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  );
259
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  }
261
- }
262
 
263
- return $accounts;
 
 
 
 
 
 
 
264
  }
265
- }
266
 
267
- return false;
 
268
  }
269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  }
271
 
272
  }
1
  <?php
2
 
3
 
4
+ class Yoast_Google_Analytics {
5
+
6
+ /**
7
+ * @var string
8
+ */
9
+ private $option_name = 'yst_ga_api';
10
+
11
+ /**
12
+ * @var array|mixed
13
+ */
14
+ private $options = array();
15
+
16
+ /**
17
+ * @var null|Yoast_Google_Analytics
18
+ */
19
+ private static $instance = null;
20
+
21
+ /**
22
+ * @var The api client object holder
23
+ */
24
+ private $client;
25
+
26
+ /**
27
+ * Singleton
28
+ *
29
+ */
30
+ protected function __construct() {
31
+
32
+ if ( is_null( self::$instance ) ) {
33
+ self::$instance = $this;
34
+ }
 
 
35
 
36
+ $this->options = $this->get_options();
37
+
38
+ // Setting the client
39
+ $this->set_client();
40
+ }
41
 
42
+ /**
43
+ * Getting the instance object
44
+ *
45
+ * This method will return the instance of itself, if instance not exists, becauses of it's called for the first
46
+ * time, the instance will be created.
47
+ *
48
+ * @return null|Yoast_Google_Analytics
49
+ */
50
+ public static function get_instance() {
51
+ if ( is_null( self::$instance ) ) {
52
+ self::$instance = new self();
53
  }
54
 
55
+ return self::$instance;
56
+ }
 
 
 
 
 
 
 
 
 
 
57
 
 
 
58
 
59
+ /**
60
+ * Check if something went wrong with API calls to Google Analytics
61
+ */
62
+ public function check_for_ga_issues() {
 
 
 
 
63
 
64
+ $last_run = get_option( 'yst_ga_last_wp_run' );
65
+ $has_failed = get_option( 'yst_ga_api_call_fail', false );
 
 
 
 
 
 
 
 
 
 
66
 
67
+ // Show error, something went wrong
68
+ if ( $has_failed && ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 48 ) ) {
69
+ $notice_type = 'warning_fetching_data';
70
 
71
+ // Authentication has been successful, so there will be an access token
72
+ if ( ! $this->client->getAccessToken() ) {
73
+ $notice_type .= '_authenticate';
74
  }
75
 
76
+ add_action( 'admin_notices', array( 'Yoast_Google_Analytics_Notice', $notice_type ) );
77
  }
78
 
79
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
+ /**
82
+ * Wrapper for authenticate the client. If authentication code is send it will get and check an access token.
83
+ *
84
+ * @param mixed $authentication_code
85
+ */
86
+ public function authenticate( $authentication_code = null ) {
87
+ // When authentication again we should clean up some stuff
88
+ $this->api_cleanup();
89
 
90
+ $this->client->authenticate_client( $authentication_code );
91
+ }
92
 
93
+ /**
94
+ * Getting the analytics profiles
95
+ *
96
+ * Doing the request to the Google analytics API and if there is a response, parses this response and return its
97
+ * array
98
+ *
99
+ * @return array
100
+ */
101
+ public function get_profiles() {
102
+ $accounts = $this->format_profile_call(
103
+ $this->do_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' )
104
+ );
105
+
106
+ if ( is_array( $accounts ) ) {
107
+ $this->save_profile_response( $accounts );
108
+
109
+ return $accounts;
110
  }
111
 
112
+ return array();
113
+ }
114
+
115
+ /**
116
+ * Doing request to Google Analytics
117
+ *
118
+ * This method will do a request to google and get the response code and body from content
119
+ *
120
+ * @param string $target_request_url
121
+ *
122
+ * @return array|null
123
+ */
124
+ public function do_request( $target_request_url ) {
125
+
126
+ $response = $this->client->do_request( $target_request_url );
127
+
128
+ if ( ! empty( $response ) ) {
129
+ return array(
130
+ 'response' => array( 'code' => $this->client->get_http_response_code() ),
131
+ 'body' => json_decode( $response->getResponseBody(), true ),
132
+ );
133
  }
134
 
135
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
 
 
137
 
138
+ /**
139
+ * Check if client has a refresh token
140
+ * @return bool
141
+ */
142
+ public function has_refresh_token() {
143
+ return ( $this->client->get_refresh_token() != '' );
144
+ }
145
 
146
+ /**
147
+ * Getting the options bases on $this->option_name from the database
148
+ *
149
+ * @return mixed
150
+ */
151
+ public function get_options() {
152
+ return get_option( $this->option_name );
153
+ }
154
+
155
+ /**
156
+ * Checks whether we'll ever be able to reach Google.
157
+ *
158
+ * @return bool
159
+ */
160
+ public function check_google_access_from_wp() {
161
+ $can_access_google = true;
162
+ if ( defined( 'WP_HTTP_BLOCK_EXTERNAL' ) && WP_HTTP_BLOCK_EXTERNAL ) {
163
+ $can_access_google = false;
164
+ if ( defined( 'WP_ACCESSIBLE_HOSTS' ) ) {
165
+ // Better to use the internal WP logic from this point forward.
166
+ $can_access_google = $this->test_connection_to_google();
167
+ }
168
  }
169
 
170
+ return $can_access_google;
171
+ }
 
 
 
 
 
 
 
 
 
172
 
173
+ /**
174
+ * Check if we can access Google Apis from this server by making a dummy connection
175
+ */
176
+ public function check_google_access() {
177
+ return $this->test_connection_to_google();
178
+ }
179
 
180
+ /**
181
+ * Updating the options based on $this->option_name and the internal property $this->options
182
+ */
183
+ protected function update_options() {
184
+ update_option( $this->option_name, $this->options );
185
+ }
186
 
187
+ /**
188
+ * Setting the client
189
+ *
190
+ * The filter is a hook to override the configuration/
191
+ */
192
+ protected function set_client() {
193
+ $config = array(
194
+ 'application_name' => 'Google Analytics by Yoast',
195
+ 'client_id' => '346753076522-21smrc6aq0hq8oij8001s57dfoo8igf5.apps.googleusercontent.com',
196
+ 'client_secret' => '5oWaEGFgp-bSrY6vWBmdPfIF',
197
+ );
198
+
199
+ $config = apply_filters( 'yst-ga-filter-ga-config', $config );
200
+
201
+ $this->client = new Yoast_Google_Analytics_Client( $config );
202
+ }
203
 
204
+ /**
205
+ * Gets an authentication URL
206
+ *
207
+ * @return mixed
208
+ */
209
+ public function create_auth_url() {
210
+ return $this->client->createAuthUrl();
211
+ }
212
 
213
+ /**
214
+ * Saving profile response in options
215
+ *
216
+ * @param array $accounts
217
+ */
218
+ protected function save_profile_response( $accounts ) {
219
+ $this->options['ga_api_response_accounts'] = $accounts;
220
 
221
+ $this->update_options();
222
+ }
 
 
 
 
 
 
 
 
223
 
224
+ /**
225
+ * Test a connection to Google
226
+ *
227
+ * @return bool
228
+ */
229
+ private function test_connection_to_google() {
230
+ $wp_http = new WP_Http();
231
+ if ( $wp_http->block_request( 'https://www.googleapis.com/analytics/v3/management/accountSummaries' ) === false ) {
232
+ return true;
233
  }
234
 
235
+ return false;
236
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
 
238
+ /**
239
+ * Format the accounts request
240
+ *
241
+ * @param $response
242
+ *
243
+ * @return mixed
244
+ */
245
+ private function format_profile_call( $response ) {
246
+
247
+ if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
248
+ if ( ! empty( $response['body']['items'] ) && is_array( $response['body']['items'] ) ) {
249
+ $accounts = array();
250
+
251
+ foreach ( $response['body']['items'] as $item ) {
252
+ // Check if webProperties is set
253
+ if ( isset( $item['webProperties'] ) ) {
254
+ $profiles = array();
255
+
256
+ foreach ( $item['webProperties'] as $property_key => $property ) {
257
+ $profiles[$property_key] = array(
258
+ 'id' => $property['id'],
259
+ 'name' => $property['name'],
260
+ 'items' => array(),
261
  );
262
 
263
+ // Check if profiles is set
264
+ if ( isset( $property['profiles'] ) ) {
265
+ foreach ( $property['profiles'] as $key => $profile ) {
266
+ $profiles[$property_key]['items'][$key] = array_merge(
267
+ $profile,
268
+ array(
269
+ 'name' => $profile['name'] . ' (' . $property['id'] . ')',
270
+ 'ua_code' => $property['id'],
271
+ )
272
+ );
273
+ }
274
+ }
275
  }
 
276
 
277
+ $accounts[$item['id']] = array(
278
+ 'id' => $item['id'],
279
+ 'ua_code' => $property['id'],
280
+ 'parent_name' => $item['name'],
281
+ 'items' => $profiles,
282
+ );
283
+
284
+ }
285
  }
 
286
 
287
+ return $accounts;
288
+ }
289
  }
290
 
291
+ return false;
292
+ }
293
+
294
+ /**
295
+ * Doing some clean up when this method is called
296
+ */
297
+ private function api_cleanup() {
298
+ delete_option( 'yst_ga_api_call_fail' );
299
+ }
300
+
301
+ }
302
+
303
+
304
+ class Yoast_Google_Analytics_Notice {
305
+
306
+ /**
307
+ * Throw a warning if no UA code is set.
308
+ */
309
+ public static function config_warning() {
310
+ self::show_error(
311
+ sprintf( __( 'Please configure your %sGoogle Analytics settings%s!', 'google-analytics-for-wordpress' ),
312
+ '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">',
313
+ '</a>'
314
+ )
315
+ );
316
+ }
317
+
318
+ /**
319
+ * Throw a warning when the fetching failed
320
+ */
321
+ public static function warning_fetching_data_authenticate() {
322
+ self::show_error(
323
+ sprintf(
324
+ __( 'It seems the authentication for the plugin has expired, please %sre-authenticate%s with Google Analytics to allow the plugin to fetch data.', 'google-analytics-for-wordpress' ),
325
+ '<a href="' . admin_url( 'admin.php?page=yst_ga_settings' ) . '">',
326
+ '</a>'
327
+ )
328
+ );
329
+ }
330
+
331
+ /**
332
+ * Throw a warning when the fetching failed
333
+ */
334
+ public static function warning_fetching_data() {
335
+ self::show_error(
336
+ sprintf(
337
+ __( 'Data is not up-to-date, there was an error in retrieving the data from Google Analytics. This error could be caused by several issues. If the error persists, please see %sthis page%s.', 'google-analytics-for-wordpress' ),
338
+ '<a href="http://yoa.st/2p">',
339
+ '</a>'
340
+ )
341
+ );
342
+ }
343
+
344
+ /**
345
+ * Showing the given error as an error div
346
+ *
347
+ * @param $error_message
348
+ */
349
+ private static function show_error( $error_message ) {
350
+ echo '<div class="error"><p>' . $error_message . '</p></div>';
351
  }
352
 
353
  }
admin/dashboards/class-admin-dashboards-api-options.php CHANGED
@@ -1,90 +1,86 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Api_Options' ) ) {
4
 
5
- class Yoast_GA_Dashboards_Api_Options {
 
 
 
 
 
6
 
7
- /**
8
- * Store this instance
9
- *
10
- * @var null
11
- */
12
- private static $instance = null;
13
 
14
- /**
15
- * Store the access token
16
- *
17
- * @var
18
- */
19
- private $access_token;
20
 
21
- /**
22
- * Store the options
23
- *
24
- * @var
25
- */
26
- private $options;
27
 
28
- /**
29
- * Construct on the dashboards class for GA
30
- */
31
- protected function __construct() {
32
- $this->set_options();
 
 
 
33
  }
34
 
35
- /**
36
- * Get the instance
37
- *
38
- * @return Yoast_GA_Dashboards
39
- */
40
- public static function get_instance() {
41
- if ( is_null( self::$instance ) ) {
42
- self::$instance = new self();
43
- }
44
-
45
- return self::$instance;
46
- }
47
 
48
- /**
49
- * Set the API options
50
- */
51
- public function set_options() {
52
- $this->options = Yoast_Google_Analytics::get_instance()->get_options();
53
 
54
- $this->set_access_token();
55
- }
56
 
57
- /**
58
- * Set the access token if we have one
59
- */
60
- private function set_access_token() {
61
- if ( isset( $this->options['ga_oauth']['access_token']['oauth_token'] ) && isset( $this->options['ga_oauth']['access_token']['oauth_token_secret'] ) ) {
62
- $this->access_token = $this->options['ga_oauth']['access_token'];
63
- }
64
  }
 
65
 
66
- /**
67
- * Get the API options
68
- *
69
- * @return mixed
70
- */
71
- public function get_options() {
72
- return $this->options;
73
- }
74
 
75
- /**
76
- * Get the access token from the options API, false on fail
77
- *
78
- * @return bool
79
- */
80
- public function get_access_token() {
81
- if ( ! empty( $this->access_token ) ) {
82
- return $this->access_token;
83
- } else {
84
- return false;
85
- }
86
  }
87
-
88
  }
89
 
90
- }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Api_Options {
4
 
5
+ /**
6
+ * Store this instance
7
+ *
8
+ * @var null
9
+ */
10
+ private static $instance = null;
11
 
12
+ /**
13
+ * Store the access token
14
+ *
15
+ * @var
16
+ */
17
+ private $access_token;
18
 
19
+ /**
20
+ * Store the options
21
+ *
22
+ * @var
23
+ */
24
+ private $options;
25
 
26
+ /**
27
+ * Construct on the dashboards class for GA
28
+ */
29
+ protected function __construct() {
30
+ $this->set_options();
31
+ }
32
 
33
+ /**
34
+ * Get the instance
35
+ *
36
+ * @return Yoast_GA_Dashboards
37
+ */
38
+ public static function get_instance() {
39
+ if ( is_null( self::$instance ) ) {
40
+ self::$instance = new self();
41
  }
42
 
43
+ return self::$instance;
44
+ }
 
 
 
 
 
 
 
 
 
 
45
 
46
+ /**
47
+ * Set the API options
48
+ */
49
+ public function set_options() {
50
+ $this->options = Yoast_Google_Analytics::get_instance()->get_options();
51
 
52
+ $this->set_access_token();
53
+ }
54
 
55
+ /**
56
+ * Set the access token if we have one
57
+ */
58
+ private function set_access_token() {
59
+ if ( isset( $this->options['ga_oauth']['access_token']['oauth_token'] ) && isset( $this->options['ga_oauth']['access_token']['oauth_token_secret'] ) ) {
60
+ $this->access_token = $this->options['ga_oauth']['access_token'];
 
61
  }
62
+ }
63
 
64
+ /**
65
+ * Get the API options
66
+ *
67
+ * @return mixed
68
+ */
69
+ public function get_options() {
70
+ return $this->options;
71
+ }
72
 
73
+ /**
74
+ * Get the access token from the options API, false on fail
75
+ *
76
+ * @return bool
77
+ */
78
+ public function get_access_token() {
79
+ if ( ! empty( $this->access_token ) ) {
80
+ return $this->access_token;
81
+ } else {
82
+ return false;
 
83
  }
 
84
  }
85
 
86
+ }
admin/dashboards/class-admin-dashboards-collector.php CHANGED
@@ -1,426 +1,440 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Collector' ) ) {
4
-
5
- class Yoast_GA_Dashboards_Collector {
6
-
7
- /**
8
- * API storage
9
- *
10
- * @package
11
- */
12
- public $api;
13
-
14
- /**
15
- * Store the active metrics
16
- *
17
- * @var
18
- */
19
- public $active_metrics;
20
-
21
- /**
22
- * Store the dimensions
23
- *
24
- * @var array
25
- */
26
- private $dimensions = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
- /**
29
- * Store the valid metrics, which should be
30
- *
31
- * @var array
32
- */
33
- private $valid_metrics = array();
 
 
 
 
 
 
 
34
 
35
- /**
36
- * Store the GA Profile ID
37
- *
38
- * @var
39
- */
40
- public $ga_profile_id;
41
 
42
- /**
43
- * Construct on the dashboards class for GA
44
- *
45
- * @param $ga_profile_id
46
- * @param $active_metrics
47
- * @param $valid_metrics
48
- */
49
- public function __construct( $ga_profile_id, $active_metrics, $valid_metrics ) {
50
- $this->ga_profile_id = $ga_profile_id;
51
 
52
- $active_metrics = $this->filter_metrics_to_dimensions( $active_metrics );
53
- $this->active_metrics = $active_metrics;
 
 
 
54
 
55
- add_filter( 'ga_dashboards_dimensions', array( $this, 'filter_dimensions' ), 10, 1 );
 
56
 
57
- $this->options = Yoast_GA_Dashboards_Api_Options::get_instance();
 
58
 
59
- $this->init_shutdown_hook();
 
 
60
  }
 
61
 
62
- /**
63
- * Fetch the data from Google Analytics and store it
64
- */
65
- public function aggregate_data() {
66
- if ( is_numeric( $this->ga_profile_id ) ) {
67
- // ProfileID is set
68
-
69
- /**
70
- * Implement the metric data first
71
- */
72
- if ( is_array( $this->active_metrics ) && count( $this->active_metrics ) >= 1 ) {
73
- $this->aggregate_metrics( $this->active_metrics );
74
- }
75
 
76
- /**
77
- * Now implement the dimensions that are set
78
- */
79
- if ( is_array( $this->dimensions ) && count( $this->dimensions ) >= 1 ) {
80
- $this->aggregate_dimensions( $this->dimensions );
81
- }
82
 
83
- } else {
84
- // Failure on authenticating, please reauthenticate
85
- }
86
- }
87
 
88
  /**
89
- * This hook runs on the shutdown to fetch data from GA
 
 
90
  */
91
- private function init_shutdown_hook() {
92
- $this->api = Yoast_Api_Libs::load_api_libraries( array( 'oauth', 'googleanalytics' ) );
93
-
94
- // Hook the WP cron event
95
- add_action( 'wp', array( $this, 'setup_wp_cron_aggregate' ) );
96
 
97
- // Hook our function to the WP cron event the fetch data daily
98
- add_action( 'yst_ga_aggregate_data', array( $this, 'aggregate_data' ) );
99
 
100
- // Check if the WP cron did run on time
101
- if ( isset( $_GET['page'] ) && ( $_GET['page'] === 'yst_ga_dashboard' || $_GET['page'] === 'yst_ga_settings' ) ) {
102
- add_action( 'shutdown', array( $this, 'check_api_call_hook' ) );
103
- }
104
- }
 
 
 
105
 
106
- /**
107
- * Check if we scheduled the WP cron event, if not, do so.
108
- */
109
- public function setup_wp_cron_aggregate() {
110
- if ( ! wp_next_scheduled( 'yst_ga_aggregate_data' ) ) {
111
- // Set the next event of fetching data
112
- wp_schedule_event( strtotime( date( 'Y-m-d', strtotime( 'tomorrow' ) ) . ' 00:05:00 ' ), 'daily', 'yst_ga_aggregate_data' );
 
 
 
 
 
 
 
 
 
 
 
113
  }
114
  }
115
 
116
- /**
117
- * Check if the WP cron did run yesterday. If not, we need to run it form here
118
- */
119
- public function check_api_call_hook( ) {
120
- $last_run = $this->get_last_aggregate_run();
121
-
122
- if ( $last_run === false ) {
123
- /**
124
- * Transient doesn't exists, so we need to run the
125
- * hook (This function runs already on Shutdown so
126
- * we can call it directly from now on)
127
- */
128
- $this->aggregate_data();
129
- } else {
130
- // Transient exists
131
- if ( Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 24 ) {
132
- $this->aggregate_data();
133
- }
134
- }
135
- }
136
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
137
 
138
- /**
139
- * Get the datetime when the aggregate data function was succesful
140
- *
141
- * @return datetime
142
- */
143
- private function get_last_aggregate_run() {
144
- return get_option( 'yst_ga_last_wp_run' );
 
 
 
 
 
 
145
  }
146
 
147
- /**
148
- * Remove metrics and set them as a dimension if needed
149
- *
150
- * @param $metrics
151
- *
152
- * @return mixed
153
- */
154
- private function filter_metrics_to_dimensions( $metrics ) {
155
- $filter_metrics = $this->get_filter_metrics();
156
 
157
- foreach ( $metrics as $key => $metric_name ) {
158
- if ( isset( $filter_metrics[$metric_name] ) ) {
159
- // Add and set the dimension
160
- $dimension = array( $filter_metrics[$metric_name] );
161
- $this->dimensions = array_merge( $this->dimensions, $dimension );
 
 
 
 
 
162
 
163
- // Remove it from the metrics after we've added it into dimensions
164
- unset( $metrics[$key] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  }
166
  }
 
 
167
 
168
- return $metrics;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
 
171
- /**
172
- * Get array with metrics which we need to filter as a dimension
173
- *
174
- * @return array
175
- */
176
- private function get_filter_metrics() {
177
- return array(
178
- 'source' => array(
179
- 'metric' => 'sessions',
180
- 'dimension' => 'source',
181
- 'storage_name' => 'source',
182
- ),
183
- 'top_pageviews' => array(
184
- 'metric' => 'pageViews',
185
- 'dimension' => 'pagePath',
186
- 'storage_name' => 'top_pageviews',
187
- ),
188
- 'top_countries' => array(
189
- 'metric' => 'sessions',
190
- 'dimension' => 'country',
191
- 'storage_name' => 'top_countries',
192
- ),
193
- );
194
  }
 
195
 
196
- /**
197
- * Filter function for adding dimensions
198
- *
199
- * @filter ga_dashboards_dimensions
200
- *
201
- * @param $dimensions
202
- *
203
- * @return array
204
- */
205
- public function filter_dimensions( $dimensions = array() ) {
206
- if ( is_array( $dimensions ) && count( $dimensions ) >= 1 ) {
207
- $dimensions = array_merge( $this->dimensions, $dimensions );
208
- $this->dimensions = $dimensions;
209
- }
210
 
211
- return $this->dimensions;
 
 
 
 
 
 
 
 
 
 
 
212
  }
 
213
 
214
- /**
215
- * Aggregate metrics from GA. This function should be called in the shutdown function.
216
- *
217
- * @param $metrics
218
- */
219
- private function aggregate_metrics( $metrics ) {
220
- foreach ( $metrics as $metric ) {
221
- $this->execute_call( $metric, date( 'Y-m-d', strtotime( '-6 weeks' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ) );
222
- }
 
 
 
 
223
  }
224
 
225
- /**
226
- * Aggregate dimensions from GA. This function should be called in the shutdown function.
227
- *
228
- * @param $dimensions
229
- */
230
- private function aggregate_dimensions( $dimensions ) {
231
- foreach ( $dimensions as $dimension ) {
232
- if ( ( isset( $dimension['id'] ) || isset( $dimension['dimension'] ) ) && isset( $dimension['metric'] ) ) {
233
- if ( isset( $dimension['id'] ) ) {
234
- $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:dimension' . $dimension['id'] );
235
- } elseif ( isset( $dimension['dimension'] ) ) {
236
- if ( isset( $dimension['storage_name'] ) ) {
237
- $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:' . $dimension['dimension'], $dimension['storage_name'] );
238
- } else {
239
- $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:' . $dimension['dimension'] );
240
- }
241
- }
242
- }
243
- }
244
  }
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  /**
247
- * Execute an API call to Google Analytics and store the data in the dashboards data class
 
248
  *
249
- * @param $metric
250
- * @param $start_date 2014-10-16
251
- * @param $end_date 2014-11-20
252
- * @param $dimensions ga:date
253
- * @param $storage_name string
254
- *
255
- * @return bool
256
  */
257
- private function execute_call( $metric, $start_date, $end_date, $dimensions = 'ga:date', $storage_name = 'auto' ) {
258
- $dimensions = $this->prepare_dimensions( $dimensions, $metric );
259
- $params = $this->build_params_for_call( $start_date, $end_date, $dimensions, $metric );
260
- $storage_type = $this->get_storage_type( $dimensions );
261
-
262
- $response = Yoast_Google_Analytics::get_instance()->do_request( 'https://www.googleapis.com/analytics/v3/data/ga?' . $params );
263
 
264
- if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
 
 
 
 
 
 
 
265
 
266
- // Success, set a transient which stores the latest runtime
267
- update_option( 'yst_ga_last_wp_run', date( 'Y-m-d' ) );
268
 
269
- $response = Yoast_Googleanalytics_Reporting::get_instance()->parse_response( $response, $storage_type, $start_date, $end_date );
270
- } else {
271
- return false;
272
- }
273
 
274
- if ( strpos( 'ga:date', $dimensions ) !== false ) {
275
- return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'datelist', $storage_name );
276
- } else {
277
- return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'table', $storage_name );
 
 
 
 
 
 
 
 
 
 
278
  }
279
  }
280
 
281
- /**
282
- * Get the storage type from dimensions
283
- *
284
- * @param $dimensions
285
- *
286
- * @return string
287
- */
288
- private function get_storage_type( $dimensions ) {
289
- if ( strpos( 'ga:date', $dimensions ) !== false ) {
290
- return 'datelist';
291
- } else {
292
- return 'table';
293
- }
294
- }
295
 
296
- /**
297
- * Prepare dimensions before adding them as a parameter in a call
298
- *
299
- * @param $dimensions
300
- *
301
- * @return string
302
- */
303
- private function prepare_dimensions( $dimensions, $metric ) {
 
 
 
 
 
 
 
 
304
  $filter_metrics = $this->get_filter_metrics();
 
305
 
306
- // Check if the dimensions param is an array, if so, glue it with implode to a comma separated string.
307
- if ( is_array( $dimensions ) ) {
308
- $dimensions = implode( ',', $dimensions );
309
- }
310
 
311
- if ( in_array( $metric, $this->valid_metrics ) ) {
312
- $dimensions = 'ga:date,' . $dimensions;
313
- } elseif ( isset( $filter_metrics[str_replace( 'ga:', '', $dimensions )] ) ) {
314
- // Make sure we don't have a ga:date property here
315
- $dimensions = str_replace( 'ga:date', '', $dimensions );
316
  }
317
 
318
- return $dimensions;
319
- }
320
-
321
- /**
322
- * Build the params for a call to Google Analytics, return them prepared for a http query
323
- *
324
- * @param $start_date
325
- * @param $end_date
326
- * @param $dimensions
327
- * @param $metric
328
- *
329
- * @return array|string
330
- */
331
- private function build_params_for_call( $start_date, $end_date, $dimensions, $metric ) {
332
- $params = array(
333
- 'ids' => 'ga:' . $this->ga_profile_id,
334
- 'start-date' => $start_date,
335
- 'end-date' => $end_date,
336
- 'dimensions' => $dimensions,
337
- 'metrics' => 'ga:' . $metric,
338
- 'max-results' => 10000,
339
- );
340
-
341
- $params = $this->add_sort_direction( $params, $dimensions, $metric );
342
- $params = http_build_query( $params );
343
-
344
- return $params;
345
- }
346
-
347
- /**
348
- * Add a sort direction if we need to (Especially on dimensions which are
349
- * listed in $this->get_filter_metrics())
350
- *
351
- * @param $params
352
- *
353
- * @return mixed
354
- */
355
- private function add_sort_direction( $params, $dimensions, $metric ) {
356
- $filter_dimensions = $this->get_filter_metrics();
357
-
358
- foreach ( $filter_dimensions as $dimension ) {
359
- if ( str_replace( 'ga:', '', $dimensions ) == $dimension['dimension'] && str_replace( 'ga:', '', $metric ) == $dimension['metric'] ) {
360
- $params['sort'] = '-ga:' . $dimension['metric'];
361
- }
362
  }
363
 
364
- return $params;
365
- }
366
-
367
- /**
368
- * Handle the response from the Google Analytics api.
369
- *
370
- * @param $response
371
- * @param $metric
372
- * @param $dimensions
373
- * @param $start_date
374
- * @param $end_date
375
- * @param $store_as
376
- * @param $storage_name
377
- *
378
- * @return bool
379
- */
380
- private function handle_response( $response, $metric, $dimensions, $start_date, $end_date, $store_as = 'table', $storage_name = 'auto' ) {
381
- if ( is_array( $response ) ) {
382
- // Success, store this data
383
- $filter_metrics = $this->get_filter_metrics();
384
- $extracted = str_replace( 'ga:', '', str_replace( 'ga:date,', '', $dimensions ) );
385
-
386
- if ( isset( $filter_metrics[$extracted] ) ) {
387
- $name = $extracted;
388
-
389
- } else {
390
- $name = $metric;
391
- }
392
-
393
- if ( $dimensions !== 'ga:date' && ! isset( $filter_metrics[$extracted] ) ) {
394
- $name = str_replace( 'ga:date,', '', $dimensions );
395
- }
396
-
397
- // Overwrite the name if we have a defined one
398
- if ( $storage_name != 'auto' ) {
399
- $name = $storage_name;
400
- }
401
 
402
- return Yoast_GA_Dashboards_Data::set( $name, $response, strtotime( $start_date ), strtotime( $end_date ), $store_as );
403
- } else {
404
- // Failure on API call try to log it
405
- $this->log_error( print_r( $response, true ) );
406
 
407
- return false;
408
- }
409
  }
 
410
 
411
- /**
412
- * Log an error while calling the Google Analytics API
413
- *
414
- * @param $error
415
- */
416
- private function log_error( $error ) {
417
- if ( true == WP_DEBUG ) {
418
- if ( function_exists( 'error_log' ) ) {
419
- error_log( 'Yoast Google Analytics (Dashboard API): ' . $error );
420
- }
421
  }
422
  }
423
-
424
  }
425
 
426
- }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Collector {
4
+
5
+ /**
6
+ * API storage
7
+ *
8
+ * @package
9
+ */
10
+ public $api;
11
+
12
+ /**
13
+ * Store the active metrics
14
+ *
15
+ * @var
16
+ */
17
+ public $active_metrics;
18
+
19
+ /**
20
+ * Store the dimensions
21
+ *
22
+ * @var array
23
+ */
24
+ private $dimensions = array();
25
+
26
+ /**
27
+ * Store the valid metrics, which should be
28
+ *
29
+ * @var array
30
+ */
31
+ private $valid_metrics = array();
32
+
33
+ /**
34
+ * Store the GA Profile ID
35
+ *
36
+ * @var
37
+ */
38
+ public $ga_profile_id;
39
+
40
+ /**
41
+ * Construct on the dashboards class for GA
42
+ *
43
+ * @param $ga_profile_id
44
+ * @param $active_metrics
45
+ * @param $valid_metrics
46
+ */
47
+ public function __construct( $ga_profile_id, $active_metrics, $valid_metrics ) {
48
+ $this->ga_profile_id = $ga_profile_id;
49
+
50
+ $active_metrics = $this->filter_metrics_to_dimensions( $active_metrics );
51
+ $this->active_metrics = $active_metrics;
52
+
53
+ add_filter( 'ga_dashboards_dimensions', array( $this, 'filter_dimensions' ), 10, 1 );
54
+
55
+ $this->options = Yoast_GA_Dashboards_Api_Options::get_instance();
56
+
57
+ $this->init_shutdown_hook();
58
+ }
59
 
60
+ /**
61
+ * Fetch the data from Google Analytics and store it
62
+ */
63
+ public function aggregate_data() {
64
+ if ( is_numeric( $this->ga_profile_id ) ) {
65
+ // ProfileID is set
66
+
67
+ /**
68
+ * Implement the metric data first
69
+ */
70
+ if ( is_array( $this->active_metrics ) && count( $this->active_metrics ) >= 1 ) {
71
+ $this->aggregate_metrics( $this->active_metrics );
72
+ }
73
 
74
+ /**
75
+ * Now implement the dimensions that are set
76
+ */
77
+ if ( is_array( $this->dimensions ) && count( $this->dimensions ) >= 1 ) {
78
+ $this->aggregate_dimensions( $this->dimensions );
79
+ }
80
 
81
+ } else {
82
+ // Failure on authenticating, please reauthenticate
83
+ }
84
+ }
 
 
 
 
 
85
 
86
+ /**
87
+ * This hook runs on the shutdown to fetch data from GA
88
+ */
89
+ private function init_shutdown_hook() {
90
+ $this->api = Yoast_Api_Libs::load_api_libraries( array( 'oauth', 'googleanalytics' ) );
91
 
92
+ // Hook the WP cron event
93
+ add_action( 'wp', array( $this, 'setup_wp_cron_aggregate' ) );
94
 
95
+ // Hook our function to the WP cron event the fetch data daily
96
+ add_action( 'yst_ga_aggregate_data', array( $this, 'aggregate_data' ) );
97
 
98
+ // Check if the WP cron did run on time
99
+ if ( isset( $_GET['page'] ) && ( $_GET['page'] === 'yst_ga_dashboard' || $_GET['page'] === 'yst_ga_settings' ) ) {
100
+ add_action( 'shutdown', array( $this, 'check_api_call_hook' ) );
101
  }
102
+ }
103
 
104
+ /**
105
+ * Check if we scheduled the WP cron event, if not, do so.
106
+ */
107
+ public function setup_wp_cron_aggregate() {
108
+ if ( ! wp_next_scheduled( 'yst_ga_aggregate_data' ) ) {
109
+ // Set the next event of fetching data
110
+ wp_schedule_event( strtotime( date( 'Y-m-d', strtotime( 'tomorrow' ) ) . ' 00:05:00 ' ), 'daily', 'yst_ga_aggregate_data' );
111
+ }
112
+ }
 
 
 
 
113
 
114
+ /**
115
+ * Check if the WP cron did run yesterday. If not, we need to run it form here
116
+ */
117
+ public function check_api_call_hook() {
118
+ $last_run = $this->get_last_aggregate_run();
 
119
 
 
 
 
 
120
 
121
  /**
122
+ * Transient doesn't exists, so we need to run the
123
+ * hook (This function runs already on Shutdown so
124
+ * we can call it directly from now on) or the last run has ben more than 24 hours
125
  */
126
+ if ( $last_run === false || Yoast_GA_Utils::hours_between( strtotime( $last_run ), time() ) >= 24 ) {
127
+ $this->aggregate_data();
128
+ }
129
+ }
 
130
 
 
 
131
 
132
+ /**
133
+ * Get the datetime when the aggregate data function was succesful
134
+ *
135
+ * @return datetime
136
+ */
137
+ private function get_last_aggregate_run() {
138
+ return get_option( 'yst_ga_last_wp_run' );
139
+ }
140
 
141
+ /**
142
+ * Remove metrics and set them as a dimension if needed
143
+ *
144
+ * @param $metrics
145
+ *
146
+ * @return mixed
147
+ */
148
+ private function filter_metrics_to_dimensions( $metrics ) {
149
+ $filter_metrics = $this->get_filter_metrics();
150
+
151
+ foreach ( $metrics as $key => $metric_name ) {
152
+ if ( isset( $filter_metrics[$metric_name] ) ) {
153
+ // Add and set the dimension
154
+ $dimension = array( $filter_metrics[$metric_name] );
155
+ $this->dimensions = array_merge( $this->dimensions, $dimension );
156
+
157
+ // Remove it from the metrics after we've added it into dimensions
158
+ unset( $metrics[$key] );
159
  }
160
  }
161
 
162
+ return $metrics;
163
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
 
165
+ /**
166
+ * Get array with metrics which we need to filter as a dimension
167
+ *
168
+ * @return array
169
+ */
170
+ private function get_filter_metrics() {
171
+ return array(
172
+ 'source' => array(
173
+ 'metric' => 'sessions',
174
+ 'dimension' => 'source',
175
+ 'storage_name' => 'source',
176
+ ),
177
+ 'top_pageviews' => array(
178
+ 'metric' => 'pageViews',
179
+ 'dimension' => 'pagePath',
180
+ 'storage_name' => 'top_pageviews',
181
+ ),
182
+ 'top_countries' => array(
183
+ 'metric' => 'sessions',
184
+ 'dimension' => 'country',
185
+ 'storage_name' => 'top_countries',
186
+ ),
187
+ );
188
+ }
189
 
190
+ /**
191
+ * Filter function for adding dimensions
192
+ *
193
+ * @filter ga_dashboards_dimensions
194
+ *
195
+ * @param $dimensions
196
+ *
197
+ * @return array
198
+ */
199
+ public function filter_dimensions( $dimensions = array() ) {
200
+ if ( is_array( $dimensions ) && count( $dimensions ) >= 1 ) {
201
+ $dimensions = array_merge( $this->dimensions, $dimensions );
202
+ $this->dimensions = $dimensions;
203
  }
204
 
205
+ return $this->dimensions;
206
+ }
 
 
 
 
 
 
 
207
 
208
+ /**
209
+ * Aggregate metrics from GA. This function should be called in the shutdown function.
210
+ *
211
+ * @param $metrics
212
+ */
213
+ private function aggregate_metrics( $metrics ) {
214
+ foreach ( $metrics as $metric ) {
215
+ $this->execute_call( $metric, date( 'Y-m-d', strtotime( '-6 weeks' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ) );
216
+ }
217
+ }
218
 
219
+ /**
220
+ * Aggregate dimensions from GA. This function should be called in the shutdown function.
221
+ *
222
+ * @param $dimensions
223
+ */
224
+ private function aggregate_dimensions( $dimensions ) {
225
+ foreach ( $dimensions as $dimension ) {
226
+ if ( ( isset( $dimension['id'] ) || isset( $dimension['dimension'] ) ) && isset( $dimension['metric'] ) ) {
227
+ if ( isset( $dimension['id'] ) ) {
228
+ $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:dimension' . $dimension['id'] );
229
+ } elseif ( isset( $dimension['dimension'] ) ) {
230
+ if ( isset( $dimension['storage_name'] ) ) {
231
+ $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:' . $dimension['dimension'], $dimension['storage_name'] );
232
+ } else {
233
+ $this->execute_call( $dimension['metric'], date( 'Y-m-d', strtotime( '-1 month' ) ), date( 'Y-m-d', strtotime( 'yesterday' ) ), 'ga:' . $dimension['dimension'] );
234
+ }
235
  }
236
  }
237
+ }
238
+ }
239
 
240
+ /**
241
+ * Execute an API call to Google Analytics and store the data in the dashboards data class
242
+ *
243
+ * @param $metric
244
+ * @param $start_date 2014-10-16
245
+ * @param $end_date 2014-11-20
246
+ * @param $dimensions ga:date
247
+ * @param $storage_name string
248
+ *
249
+ * @return bool
250
+ */
251
+ private function execute_call( $metric, $start_date, $end_date, $dimensions = 'ga:date', $storage_name = 'auto' ) {
252
+ $dimensions = $this->prepare_dimensions( $dimensions, $metric );
253
+ $params = $this->build_params_for_call( $start_date, $end_date, $dimensions, $metric );
254
+ $storage_type = $this->get_storage_type( $dimensions );
255
+
256
+ $response = Yoast_Google_Analytics::get_instance()->do_request( 'https://www.googleapis.com/analytics/v3/data/ga?' . $params );
257
+
258
+ if ( isset( $response['response']['code'] ) && $response['response']['code'] == 200 ) {
259
+
260
+ // Delete option api_fail because there it's successful now
261
+ delete_option( 'yst_ga_api_call_fail' );
262
+
263
+ // Success, set a transient which stores the latest runtime
264
+ update_option( 'yst_ga_last_wp_run', date( 'Y-m-d' ) );
265
+
266
+ $response = Yoast_Googleanalytics_Reporting::get_instance()->parse_response( $response, $storage_type, $start_date, $end_date );
267
+ } else {
268
+ // When response is failing, we should count the number of
269
+ $this->save_api_failure();
270
+
271
+ return false;
272
  }
273
 
274
+ if ( strpos( 'ga:date', $dimensions ) !== false ) {
275
+ return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'datelist', $storage_name );
276
+ } else {
277
+ return $this->handle_response( $response, $metric, $dimensions, $start_date, $end_date, 'table', $storage_name );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
278
  }
279
+ }
280
 
281
+ /**
282
+ * When the API isn't able to get a successful response (code 200), we have to save that the call has failed
283
+ *
284
+ */
285
+ private function save_api_failure() {
286
+ update_option( 'yst_ga_api_call_fail', true );
287
+ }
 
 
 
 
 
 
 
288
 
289
+ /**
290
+ * Get the storage type from dimensions
291
+ *
292
+ * @param $dimensions
293
+ *
294
+ * @return string
295
+ */
296
+ private function get_storage_type( $dimensions ) {
297
+ if ( strpos( 'ga:date', $dimensions ) !== false ) {
298
+ return 'datelist';
299
+ } else {
300
+ return 'table';
301
  }
302
+ }
303
 
304
+ /**
305
+ * Prepare dimensions before adding them as a parameter in a call
306
+ *
307
+ * @param $dimensions
308
+ *
309
+ * @return string
310
+ */
311
+ private function prepare_dimensions( $dimensions, $metric ) {
312
+ $filter_metrics = $this->get_filter_metrics();
313
+
314
+ // Check if the dimensions param is an array, if so, glue it with implode to a comma separated string.
315
+ if ( is_array( $dimensions ) ) {
316
+ $dimensions = implode( ',', $dimensions );
317
  }
318
 
319
+ if ( in_array( $metric, $this->valid_metrics ) ) {
320
+ $dimensions = 'ga:date,' . $dimensions;
321
+ } elseif ( isset( $filter_metrics[str_replace( 'ga:', '', $dimensions )] ) ) {
322
+ // Make sure we don't have a ga:date property here
323
+ $dimensions = str_replace( 'ga:date', '', $dimensions );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  }
325
 
326
+ return $dimensions;
327
+ }
328
+
329
+ /**
330
+ * Build the params for a call to Google Analytics, return them prepared for a http query
331
+ *
332
+ * @param $start_date
333
+ * @param $end_date
334
+ * @param $dimensions
335
+ * @param $metric
336
+ *
337
+ * @return array|string
338
+ */
339
+ private function build_params_for_call( $start_date, $end_date, $dimensions, $metric ) {
340
  /**
341
+ * Filter: 'yst-ga-filter-api-limit' - Allow people to change the max results value in the API
342
+ * calls. Default value is 1000 results per call.
343
  *
344
+ * @api int 1000
 
 
 
 
 
 
345
  */
346
+ $api_call_limit = apply_filters( 'yst-ga-filter-api-limit', 1000 );
 
 
 
 
 
347
 
348
+ $params = array(
349
+ 'ids' => 'ga:' . $this->ga_profile_id,
350
+ 'start-date' => $start_date,
351
+ 'end-date' => $end_date,
352
+ 'dimensions' => $dimensions,
353
+ 'metrics' => 'ga:' . $metric,
354
+ 'max-results' => $api_call_limit,
355
+ );
356
 
357
+ $params = $this->add_sort_direction( $params, $dimensions, $metric );
358
+ $params = http_build_query( $params );
359
 
360
+ return $params;
361
+ }
 
 
362
 
363
+ /**
364
+ * Add a sort direction if we need to (Especially on dimensions which are
365
+ * listed in $this->get_filter_metrics())
366
+ *
367
+ * @param $params
368
+ *
369
+ * @return mixed
370
+ */
371
+ private function add_sort_direction( $params, $dimensions, $metric ) {
372
+ $filter_dimensions = $this->get_filter_metrics();
373
+
374
+ foreach ( $filter_dimensions as $dimension ) {
375
+ if ( str_replace( 'ga:', '', $dimensions ) == $dimension['dimension'] && str_replace( 'ga:', '', $metric ) == $dimension['metric'] ) {
376
+ $params['sort'] = '-ga:' . $dimension['metric'];
377
  }
378
  }
379
 
380
+ return $params;
381
+ }
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
+ /**
384
+ * Handle the response from the Google Analytics api.
385
+ *
386
+ * @param $response
387
+ * @param $metric
388
+ * @param $dimensions
389
+ * @param $start_date
390
+ * @param $end_date
391
+ * @param $store_as
392
+ * @param $storage_name
393
+ *
394
+ * @return bool
395
+ */
396
+ private function handle_response( $response, $metric, $dimensions, $start_date, $end_date, $store_as = 'table', $storage_name = 'auto' ) {
397
+ if ( is_array( $response ) ) {
398
+ // Success, store this data
399
  $filter_metrics = $this->get_filter_metrics();
400
+ $extracted = str_replace( 'ga:', '', str_replace( 'ga:date,', '', $dimensions ) );
401
 
402
+ if ( isset( $filter_metrics[$extracted] ) ) {
403
+ $name = $extracted;
 
 
404
 
405
+ } else {
406
+ $name = $metric;
 
 
 
407
  }
408
 
409
+ if ( $dimensions !== 'ga:date' && ! isset( $filter_metrics[$extracted] ) ) {
410
+ $name = str_replace( 'ga:date,', '', $dimensions );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  }
412
 
413
+ // Overwrite the name if we have a defined one
414
+ if ( $storage_name != 'auto' ) {
415
+ $name = $storage_name;
416
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
+ return Yoast_GA_Dashboards_Data::set( $name, $response, strtotime( $start_date ), strtotime( $end_date ), $store_as );
419
+ } else {
420
+ // Failure on API call try to log it
421
+ $this->log_error( print_r( $response, true ) );
422
 
423
+ return false;
 
424
  }
425
+ }
426
 
427
+ /**
428
+ * Log an error while calling the Google Analytics API
429
+ *
430
+ * @param $error
431
+ */
432
+ private function log_error( $error ) {
433
+ if ( true == WP_DEBUG ) {
434
+ if ( function_exists( 'error_log' ) ) {
435
+ error_log( 'Google Analytics by Yoast (Dashboard API): ' . $error );
 
436
  }
437
  }
 
438
  }
439
 
440
+ }
admin/dashboards/class-admin-dashboards-data.php CHANGED
@@ -7,53 +7,59 @@
7
  * You can retrieve the data by using the function Yoast_GA_Dashboards_Data::get() in this
8
  * class.
9
  */
 
10
 
11
- if ( ! class_exists( 'Yoast_GA_Dashboards_Data' ) ) {
 
 
 
 
 
 
 
 
12
 
13
- class Yoast_GA_Dashboards_Data {
14
-
15
- /**
16
- * Get a data object
17
- *
18
- * @param $type String
19
- *
20
- * @return array
21
- */
22
- public static function get( $type ) {
23
- $option = get_option( 'yst_ga_' . $type );
24
 
25
- if ( false === $option ) {
26
- // Option does not exist, abort
27
- return array();
28
- }
29
 
30
- // @TODO loop through transient to get the correct date range
 
31
 
32
- return $option;
33
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
 
35
- /**
36
- * Save a data object
37
- *
38
- * @param $type
39
- * @param $value
40
- * @param $start_date
41
- * @param $end_date
42
- * @param $store_as
43
- *
44
- * @return bool
45
- */
46
- public static function set( $type, $value, $start_date, $end_date, $store_as ) {
47
- $store = array(
48
- 'store_as' => $store_as,
49
- 'type' => $type,
50
- 'start_date' => $start_date,
51
- 'end_date' => $end_date,
52
- 'value' => $value,
53
- );
54
-
55
- return update_option( 'yst_ga_' . $type, $store );
56
- }
57
  }
58
 
 
 
 
 
 
 
 
 
 
 
59
  }
7
  * You can retrieve the data by using the function Yoast_GA_Dashboards_Data::get() in this
8
  * class.
9
  */
10
+ class Yoast_GA_Dashboards_Data {
11
 
12
+ /**
13
+ * Get a data object
14
+ *
15
+ * @param $type String
16
+ *
17
+ * @return array
18
+ */
19
+ public static function get( $type ) {
20
+ $option = get_option( 'yst_ga_' . $type );
21
 
22
+ if ( false === $option ) {
23
+ // Option does not exist, abort
24
+ return array();
25
+ }
 
 
 
 
 
 
 
26
 
27
+ // @TODO loop through transient to get the correct date range
 
 
 
28
 
29
+ return $option;
30
+ }
31
 
32
+ /**
33
+ * Save a data object
34
+ *
35
+ * @param $type
36
+ * @param $value
37
+ * @param $start_date
38
+ * @param $end_date
39
+ * @param $store_as
40
+ *
41
+ * @return bool
42
+ */
43
+ public static function set( $type, $value, $start_date, $end_date, $store_as ) {
44
+ $store = array(
45
+ 'store_as' => $store_as,
46
+ 'type' => $type,
47
+ 'start_date' => $start_date,
48
+ 'end_date' => $end_date,
49
+ 'value' => $value,
50
+ );
51
 
52
+ return update_option( 'yst_ga_' . $type, $store );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  }
54
 
55
+ /**
56
+ * Reset an option of the GA dashboards storage engine
57
+ *
58
+ * @param $type
59
+ *
60
+ * @return bool
61
+ */
62
+ public static function reset( $type ) {
63
+ return update_option( 'yst_ga_' . $type, array() );
64
+ }
65
  }
admin/dashboards/class-admin-dashboards-display.php CHANGED
@@ -1,140 +1,136 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Display' ) ) {
4
-
5
- class Yoast_GA_Dashboards_Display {
6
-
7
- /**
8
- * Property for holding instance of itself
9
- *
10
- * @var Yoast_GA_Dashboards_Display
11
- */
12
- protected static $instance;
13
-
14
- /**
15
- * Container for holding the setted dashboards
16
- *
17
- * @var array
18
- */
19
- protected $dashboards = array();
20
-
21
- /**
22
- * @var array The dashboard types which can be used
23
- */
24
- protected $dashboard_types = array( 'graph', 'table' );
25
-
26
- /**
27
- * @var array For each dashboard type there will be created a driver that will be stored in this property
28
- */
29
- protected $drivers = array();
30
-
31
- /**
32
- * For the use of singleton pattern. Create instance of itself and return his instance
33
- *
34
- * @return Yoast_GA_Dasboards_Graph
35
- */
36
- public static function get_instance() {
37
-
38
- if ( is_null( self::$instance ) ) {
39
- self::$instance = new self();
40
- }
41
-
42
- return self::$instance;
43
- }
44
-
45
- /**
46
- * Protected constructor to prevent creating a new instance of the
47
- * *Singleton* via the `new` operator from outside of this class.
48
- */
49
- protected function __construct() {
50
- foreach ( $this->dashboard_types AS $dashboard_type ) {
51
- if ( ! $this->driver_exists( $dashboard_type ) ) {
52
- $this->create_driver( $dashboard_type );
53
- }
54
- }
55
  }
56
 
57
- /**
58
- * Get the driver from property, this->drivers
59
- *
60
- * If driver doesn't exist, it will be created first
61
- *
62
- * @param string $dashboard_type - The name of the driver that will be returned
63
- *
64
- * @return object
65
- */
66
- private function driver( $dashboard_type ) {
67
 
 
 
 
 
 
 
68
  if ( ! $this->driver_exists( $dashboard_type ) ) {
69
  $this->create_driver( $dashboard_type );
70
  }
 
 
71
 
72
- return $this->drivers[$dashboard_type];
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
- /**
76
- * Adding dashboards to $this->dashboard en register them to the driver by $this->register
77
- *
78
- * @param array $dashboards
79
- */
80
- public function add_dashboards( $dashboards ) {
81
- // Save all dashboards to property - for future use
82
- $this->dashboards = array_merge( $this->dashboards, $dashboards );
 
 
 
83
 
84
- $this->register( $dashboards );
85
- }
86
 
87
- /**
88
- * Register dashboards to the drivers
89
- *
90
- * @param array $dashboards
91
- */
92
- private function register( $dashboards ) {
93
- foreach ( $dashboards AS $dashboard_name => $dashboard_settings ) {
94
- if ( ! empty( $dashboard_settings['type'] ) ) {
95
- $this->driver( $dashboard_settings['type'] )->register( $dashboard_name, $dashboard_settings );
96
- }
97
  }
98
  }
 
99
 
100
- /**
101
- * Displaying the $dashboards on the screen. If $dashboards isn't given it will display all registered
102
- * dashboards
103
- *
104
- * @param string $tab_to_show
105
- */
106
- public function display( $tab_to_show ) {
107
 
108
- $dashboards_to_show = $this->dashboards;
109
 
110
- foreach ( $dashboards_to_show AS $dashboard_name => $dashboard_settings ) {
111
- if ( !empty($dashboard_settings['tab']) && $dashboard_settings['tab'] === $tab_to_show ) {
112
- $this->driver( $dashboard_settings['type'] )->display( $dashboard_name );
113
- }
114
  }
115
  }
 
116
 
117
- /**
118
- * Check if given $dashboard_type exists and if it's an object
119
- *
120
- * @param string $dashboard_type
121
- *
122
- * @return bool
123
- */
124
- protected function driver_exists( $dashboard_type ) {
125
- return array_key_exists( $dashboard_type, $this->drivers ) && is_object( $this->drivers[$dashboard_type] );
126
- }
127
-
128
- /**
129
- * Creates a driver based on given $dashboard_type
130
- *
131
- * @param $dashboard_type
132
- */
133
- protected function create_driver( $dashboard_type ) {
134
- $driver_class = 'Yoast_GA_Dashboards_' . ucfirst( $dashboard_type );
135
- $this->drivers[$dashboard_type] = new $driver_class();
136
- }
137
 
 
 
 
 
 
 
 
 
138
  }
139
 
140
- }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Display {
4
+
5
+ /**
6
+ * Property for holding instance of itself
7
+ *
8
+ * @var Yoast_GA_Dashboards_Display
9
+ */
10
+ protected static $instance;
11
+
12
+ /**
13
+ * Container for holding the setted dashboards
14
+ *
15
+ * @var array
16
+ */
17
+ protected $dashboards = array();
18
+
19
+ /**
20
+ * @var array The dashboard types which can be used
21
+ */
22
+ protected $dashboard_types = array( 'graph', 'table' );
23
+
24
+ /**
25
+ * @var array For each dashboard type there will be created a driver that will be stored in this property
26
+ */
27
+ protected $drivers = array();
28
+
29
+ /**
30
+ * For the use of singleton pattern. Create instance of itself and return his instance
31
+ *
32
+ * @return Yoast_GA_Dasboards_Graph
33
+ */
34
+ public static function get_instance() {
35
+
36
+ if ( is_null( self::$instance ) ) {
37
+ self::$instance = new self();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
+ return self::$instance;
41
+ }
 
 
 
 
 
 
 
 
42
 
43
+ /**
44
+ * Protected constructor to prevent creating a new instance of the
45
+ * *Singleton* via the `new` operator from outside of this class.
46
+ */
47
+ protected function __construct() {
48
+ foreach ( $this->dashboard_types AS $dashboard_type ) {
49
  if ( ! $this->driver_exists( $dashboard_type ) ) {
50
  $this->create_driver( $dashboard_type );
51
  }
52
+ }
53
+ }
54
 
55
+ /**
56
+ * Get the driver from property, this->drivers
57
+ *
58
+ * If driver doesn't exist, it will be created first
59
+ *
60
+ * @param string $dashboard_type - The name of the driver that will be returned
61
+ *
62
+ * @return object
63
+ */
64
+ private function driver( $dashboard_type ) {
65
+
66
+ if ( ! $this->driver_exists( $dashboard_type ) ) {
67
+ $this->create_driver( $dashboard_type );
68
  }
69
 
70
+ return $this->drivers[$dashboard_type];
71
+ }
72
+
73
+ /**
74
+ * Adding dashboards to $this->dashboard en register them to the driver by $this->register
75
+ *
76
+ * @param array $dashboards
77
+ */
78
+ public function add_dashboards( $dashboards ) {
79
+ // Save all dashboards to property - for future use
80
+ $this->dashboards = array_merge( $this->dashboards, $dashboards );
81
 
82
+ $this->register( $dashboards );
83
+ }
84
 
85
+ /**
86
+ * Register dashboards to the drivers
87
+ *
88
+ * @param array $dashboards
89
+ */
90
+ private function register( $dashboards ) {
91
+ foreach ( $dashboards AS $dashboard_name => $dashboard_settings ) {
92
+ if ( ! empty( $dashboard_settings['type'] ) ) {
93
+ $this->driver( $dashboard_settings['type'] )->register( $dashboard_name, $dashboard_settings );
 
94
  }
95
  }
96
+ }
97
 
98
+ /**
99
+ * Displaying the $dashboards on the screen. If $dashboards isn't given it will display all registered
100
+ * dashboards
101
+ *
102
+ * @param string $tab_to_show
103
+ */
104
+ public function display( $tab_to_show ) {
105
 
106
+ $dashboards_to_show = $this->dashboards;
107
 
108
+ foreach ( $dashboards_to_show AS $dashboard_name => $dashboard_settings ) {
109
+ if ( ! empty( $dashboard_settings['tab'] ) && $dashboard_settings['tab'] === $tab_to_show ) {
110
+ $this->driver( $dashboard_settings['type'] )->display( $dashboard_name );
 
111
  }
112
  }
113
+ }
114
 
115
+ /**
116
+ * Check if given $dashboard_type exists and if it's an object
117
+ *
118
+ * @param string $dashboard_type
119
+ *
120
+ * @return bool
121
+ */
122
+ protected function driver_exists( $dashboard_type ) {
123
+ return array_key_exists( $dashboard_type, $this->drivers ) && is_object( $this->drivers[$dashboard_type] );
124
+ }
 
 
 
 
 
 
 
 
 
 
125
 
126
+ /**
127
+ * Creates a driver based on given $dashboard_type
128
+ *
129
+ * @param $dashboard_type
130
+ */
131
+ protected function create_driver( $dashboard_type ) {
132
+ $driver_class = 'Yoast_GA_Dashboards_' . ucfirst( $dashboard_type );
133
+ $this->drivers[$dashboard_type] = new $driver_class();
134
  }
135
 
136
+ }
admin/dashboards/class-admin-dashboards.php CHANGED
@@ -1,102 +1,68 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards' ) ) {
4
-
5
- class Yoast_GA_Dashboards {
6
-
7
- /**
8
- * Store the data aggregator
9
- *
10
- * @package
11
- */
12
- public $aggregator;
13
-
14
- /**
15
- * Store the Data instance
16
- *
17
- * @package
18
- */
19
- public $data;
20
-
21
- /**
22
- * Store the active metrics
23
- *
24
- * @var
25
- */
26
- public $active_metrics;
27
-
28
- /**
29
- * Store the valid metrics which are available in the Google API, more can be added
30
- *
31
- * @var array
32
- *
33
- * @link https://ga-dev-tools.appspot.com/explorer/
34
- */
35
- private $valid_metrics = array( 'sessions', 'bounces', 'users', 'newUsers', 'percentNewSessions', 'bounceRate', 'sessionDuration', 'avgSessionDuration', 'hits' );
36
-
37
- /**
38
- * Store this instance
39
- *
40
- * @var null
41
- */
42
- private static $instance = null;
43
-
44
- /**
45
- * Construct on the dashboards class for GA
46
- */
47
- protected function __construct() {
48
- add_filter( 'ga_extend_dashboards', array( $this, 'extend_dashboards' ), 10, 1 );
49
- }
 
 
 
 
 
 
 
50
 
51
- /**
52
- * Init the dashboards
53
- *
54
- * @param integer $ga_profile_id
55
- */
56
- public function init_dashboards( $ga_profile_id ) {
57
-
58
- $dashboards = array(
59
- 'sessions' => array(
60
- 'title' => __( 'Sessions', 'google-analytics-for-wordpress' ),
61
- 'help' => __( 'A session is a group of interactions that take place on your website within a given time frame. For example a single session can contain multiple screen or page views, events, social interactions, and ecommerce transactions. <a href="http://yoa.st/gasessions" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
62
- 'type' => 'graph',
63
- 'tab' => 'general',
64
- ),
65
- 'bounceRate' => array(
66
- 'title' => __( 'Bounce rate', 'google-analytics-for-wordpress' ),
67
- 'help' => __( 'Bounce Rate is the percentage of single-page sessions (i.e. sessions in which the person left your site from the entrance page without interacting with the page). <a href="http://yoa.st/gabounce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
68
- 'data-percent' => true,
69
- 'type' => 'graph',
70
- 'tab' => 'general',
71
- ),
72
- 'source' => array(
73
- 'title' => __( 'Traffic sources', 'google-analytics-for-wordpress' ),
74
- 'help' => __( 'Every referral to a web site has an origin, or (traffic) source. Possible sources include: “google” (the name of a search engine), “facebook.com” (the name of a referring site), “spring_newsletter” (the name of one of your newsletters), and “direct” (users that typed your URL directly into their browser, or who had bookmarked your site). <a href="http://yoa.st/gabnce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
75
- 'type' => 'table',
76
- 'columns' => array(
77
- __( 'Sessions', 'google-analytics-for-wordpress' )
78
- ),
79
- 'tab' => 'dimensions',
80
- ),
81
- 'top_pageviews' => array(
82
- 'title' => __( 'Popular pages', 'google-analytics-for-wordpress' ),
83
- 'help' => __( 'Pages by url.', 'google-analytics-for-wordpress' ),
84
- 'type' => 'table',
85
- 'columns' => array(
86
- __( 'Sessions', 'google-analytics-for-wordpress' )
87
- ),
88
- 'tab' => 'dimensions',
89
- ),
90
- 'top_countries' => array(
91
- 'title' => __( 'Countries', 'google-analytics-for-wordpress' ),
92
- 'help' => __( 'The country or territory from which visits originated. <a href="http://yoa.st/gacountry" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
93
- 'type' => 'table',
94
- 'columns' => array(
95
- __( 'Sessions', 'google-analytics-for-wordpress' )
96
- ),
97
- 'tab' => 'dimensions',
98
- ),
99
- );
100
 
101
  $this->extend_dashboards( $dashboards );
102
 
@@ -107,111 +73,183 @@ if ( ! class_exists( 'Yoast_GA_Dashboards' ) ) {
107
 
108
  $this->register( $register );
109
  }
 
110
 
111
- /**
112
- * Adding dashboards for front-end
113
- *
114
- * By hook as filter: $dashboards = apply_filters( 'ga_extend_dashboards', $dashboards);
115
- *
116
- * @param $dashboards
117
- *
118
- * @return mixed
119
- */
120
- public function extend_dashboards( $dashboards ) {
121
- // Initialize the dashboard graphs
122
- Yoast_GA_Dashboards_Display::get_instance()->add_dashboards( $dashboards );
123
-
124
- return $dashboards;
 
 
 
 
 
 
 
 
 
 
125
  }
126
 
127
- /**
128
- * Get the instance
129
- *
130
- * @return Yoast_GA_Dashboards
131
- */
132
- public static function get_instance() {
133
- if ( is_null( self::$instance ) ) {
134
- self::$instance = new self();
135
- }
136
 
137
- return self::$instance;
 
 
 
 
 
 
 
 
 
138
  }
139
 
140
- /**
141
- * Register the dashboard types
142
- *
143
- * @param $types array or singular string
144
- *
145
- * @return bool
146
- */
147
- public function register( $types ) {
148
- if ( is_array( $types ) == false ) {
149
- $types = array( $types );
150
  }
 
151
 
152
- if ( is_array( $types ) && count( $types ) >= 1 ) {
153
- if ( $this->validate_dashboard_types( $types ) ) {
154
- $this->active_metrics = $types;
155
 
156
- return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  }
158
- }
159
 
160
- return false;
 
 
 
 
161
  }
162
 
163
- /**
164
- * Adding translations to ga-admin-dashboard
165
- */
166
- public function add_dashboard_js_translations() {
167
- // Now we can localize the script with our data.
168
- $translation_array = array(
169
- // For datatables
170
- 'sort_ascending' => __( ': activate to sort column ascending', 'google-analytics-for-wordpress' ),
171
- 'sort_descending' => __( ': activate to sort column descending', 'google-analytics-for-wordpress' ),
172
- 'empty_table' => __( 'No data available', 'google-analytics-for-wordpress' ),
173
- 'info' => _x( 'Showing _START_ to _END_ of _TOTAL_ rows', '_START_, _END_ and _TOTAL_ will be replaced by JS (See: http://datatables.net/reference/option/language.info)', 'google-analytics-for-wordpress' ),
174
- 'info_empty' => __( 'No rows to show', 'google-analytics-for-wordpress' ),
175
- 'info_filtered' => _x( '(filtered from _MAX_ total rows)', '_MAX_ will be replaced by JS (See: http://datatables.net/reference/option/language.infoFiltered)', 'google-analytics-for-wordpress' ),
176
- 'length_menu' => _x( 'Show _MENU_ rows', '_MAX_ will be replaced by JS', 'google-analytics-for-wordpress' ),
177
- 'loading_records' => __( 'Loading...', 'google-analytics-for-wordpress' ),
178
- 'pagination_first' => __( 'First', 'google-analytics-for-wordpress' ),
179
- 'pagination_last' => __( 'Last', 'google-analytics-for-wordpress' ),
180
- 'pagination_next' => __( 'Next', 'google-analytics-for-wordpress' ),
181
- 'pagination_previous' => __( 'Previous', 'google-analytics-for-wordpress' ),
182
- 'processing' => __( 'Processing...', 'google-analytics-for-wordpress' ),
183
- 'search_placeholder' => __( 'Search', 'google-analytics-for-wordpress' ),
184
- 'zero_records' => __( 'No matching records found', 'google-analytics-for-wordpress' ),
185
-
186
- // For dimensions
187
- 'dimensions' => __( 'Reports', 'google-analytics-for-wordpress' ),
188
- 'custom_dimensions' => __( 'Custom dimension reports', 'google-analytics-for-wordpress' ),
189
- );
190
-
191
- wp_localize_script( 'ga-admin-dashboard', 'dashboard_translate', $translation_array );
192
 
193
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
194
 
195
- /**
196
- * Validate the registered types of dashboards
197
- *
198
- * @param $types
199
- *
200
- * @return bool
201
- */
202
- private function validate_dashboard_types( $types ) {
203
- $valid = true;
204
-
205
- if ( is_array( $types ) ) {
206
- foreach ( $types as $check_type ) {
207
- if ( ! in_array( $check_type, $this->valid_metrics ) ) {
208
- $valid = false;
209
- }
210
  }
211
  }
212
-
213
- return $valid;
214
  }
215
- }
216
 
217
- }
 
 
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards {
4
+
5
+ /**
6
+ * Store the data aggregator
7
+ *
8
+ * @package
9
+ */
10
+ public $aggregator;
11
+
12
+ /**
13
+ * Store the Data instance
14
+ *
15
+ * @package
16
+ */
17
+ public $data;
18
+
19
+ /**
20
+ * Store the active metrics
21
+ *
22
+ * @var
23
+ */
24
+ public $active_metrics;
25
+
26
+ /**
27
+ * Store the valid metrics which are available in the Google API, more can be added
28
+ *
29
+ * @var array
30
+ *
31
+ * @link https://ga-dev-tools.appspot.com/explorer/
32
+ */
33
+ private $valid_metrics = array( 'sessions', 'bounces', 'users', 'newUsers', 'percentNewSessions', 'bounceRate', 'sessionDuration', 'avgSessionDuration', 'hits' );
34
+
35
+ /**
36
+ * Store this instance
37
+ *
38
+ * @var null
39
+ */
40
+ private static $instance = null;
41
+
42
+ /**
43
+ * Store the Dashboards disabled bool
44
+ *
45
+ * @var bool
46
+ */
47
+ private $dashboards_disabled;
48
+
49
+ /**
50
+ * Construct on the dashboards class for GA
51
+ */
52
+ protected function __construct() {
53
+ add_filter( 'ga_extend_dashboards', array( $this, 'extend_dashboards' ), 10, 1 );
54
+
55
+ $this->dashboards_disabled = Yoast_GA_Settings::get_instance()->dashboards_disabled();
56
+ }
57
 
58
+ /**
59
+ * Init the dashboards
60
+ *
61
+ * @param integer $ga_profile_id
62
+ */
63
+ public function init_dashboards( $ga_profile_id ) {
64
+ if ( ! $this->dashboards_disabled ) {
65
+ $dashboards = $this->get_default_dashboards();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
 
67
  $this->extend_dashboards( $dashboards );
68
 
73
 
74
  $this->register( $register );
75
  }
76
+ }
77
 
78
+ /**
79
+ * Adding dashboards for front-end
80
+ *
81
+ * By hook as filter: $dashboards = apply_filters( 'ga_extend_dashboards', $dashboards);
82
+ *
83
+ * @param $dashboards
84
+ *
85
+ * @return mixed
86
+ */
87
+ public function extend_dashboards( $dashboards ) {
88
+ // Initialize the dashboard graphs
89
+ Yoast_GA_Dashboards_Display::get_instance()->add_dashboards( $dashboards );
90
+
91
+ return $dashboards;
92
+ }
93
+
94
+ /**
95
+ * Get the instance
96
+ *
97
+ * @return Yoast_GA_Dashboards
98
+ */
99
+ public static function get_instance() {
100
+ if ( is_null( self::$instance ) ) {
101
+ self::$instance = new self();
102
  }
103
 
104
+ return self::$instance;
105
+ }
 
 
 
 
 
 
 
106
 
107
+ /**
108
+ * Register the dashboard types
109
+ *
110
+ * @param $types array or singular string
111
+ *
112
+ * @return bool
113
+ */
114
+ public function register( $types ) {
115
+ if ( is_array( $types ) == false ) {
116
+ $types = array( $types );
117
  }
118
 
119
+ if ( is_array( $types ) && count( $types ) >= 1 ) {
120
+ if ( $this->validate_dashboard_types( $types ) ) {
121
+ $this->active_metrics = $types;
122
+
123
+ return true;
 
 
 
 
 
124
  }
125
+ }
126
 
127
+ return false;
128
+ }
 
129
 
130
+ /**
131
+ * Adding translations to ga-admin-dashboard
132
+ */
133
+ public function add_dashboard_js_translations() {
134
+ // Now we can localize the script with our data.
135
+ $translation_array = array(
136
+ // For datatables
137
+ 'sort_ascending' => __( ': activate to sort column ascending', 'google-analytics-for-wordpress' ),
138
+ 'sort_descending' => __( ': activate to sort column descending', 'google-analytics-for-wordpress' ),
139
+ 'empty_table' => __( 'No data available', 'google-analytics-for-wordpress' ),
140
+ 'info' => _x( 'Showing _START_ to _END_ of _TOTAL_ rows', '_START_, _END_ and _TOTAL_ will be replaced by JS (See: http://datatables.net/reference/option/language.info)', 'google-analytics-for-wordpress' ),
141
+ 'info_empty' => __( 'No rows to show', 'google-analytics-for-wordpress' ),
142
+ 'info_filtered' => _x( '(filtered from _MAX_ total rows)', '_MAX_ will be replaced by JS (See: http://datatables.net/reference/option/language.infoFiltered)', 'google-analytics-for-wordpress' ),
143
+ 'length_menu' => _x( 'Show _MENU_ rows', '_MAX_ will be replaced by JS', 'google-analytics-for-wordpress' ),
144
+ 'loading_records' => __( 'Loading...', 'google-analytics-for-wordpress' ),
145
+ 'pagination_first' => __( 'First', 'google-analytics-for-wordpress' ),
146
+ 'pagination_last' => __( 'Last', 'google-analytics-for-wordpress' ),
147
+ 'pagination_next' => __( 'Next', 'google-analytics-for-wordpress' ),
148
+ 'pagination_previous' => __( 'Previous', 'google-analytics-for-wordpress' ),
149
+ 'processing' => __( 'Processing...', 'google-analytics-for-wordpress' ),
150
+ 'search_placeholder' => __( 'Search', 'google-analytics-for-wordpress' ),
151
+ 'zero_records' => __( 'No matching records found', 'google-analytics-for-wordpress' ),
152
+
153
+ // For dimensions
154
+ 'dimensions' => __( 'Reports', 'google-analytics-for-wordpress' ),
155
+ 'custom_dimensions' => __( 'Custom dimension reports', 'google-analytics-for-wordpress' ),
156
+ );
157
+
158
+ wp_localize_script( 'ga-admin-dashboard', 'dashboard_translate', $translation_array );
159
+ }
160
+
161
+ /**
162
+ * Reset all dashboards data by removing the options of the registered dashboards
163
+ *
164
+ * @return bool
165
+ */
166
+ public function reset_dashboards_data() {
167
+ if ( ! $this->dashboards_disabled ) {
168
+ $dashboards = $this->get_default_dashboards();
169
+
170
+ if ( is_array( $dashboards ) && count( $dashboards ) >= 1 ) {
171
+ foreach ( $dashboards as $name => $board ) {
172
+ Yoast_GA_Dashboards_Data::reset( $name );
173
  }
 
174
 
175
+ // Make sure we fetch new data if we enable the dashboards by updating the last_run option
176
+ update_option( 'yst_ga_last_wp_run', date( 'Y-m-d', strtotime( '-2 days' ) ) );
177
+
178
+ return true;
179
+ }
180
  }
181
 
182
+ return false;
183
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
+ /**
186
+ * Get the defaults dashboard array to register
187
+ *
188
+ * @return array
189
+ */
190
+ private function get_default_dashboards() {
191
+ return array(
192
+ 'sessions' => array(
193
+ 'title' => __( 'Sessions', 'google-analytics-for-wordpress' ),
194
+ 'help' => __( 'A session is a group of interactions that take place on your website within a given time frame. For example a single session can contain multiple screen or page views, events, social interactions, and ecommerce transactions. <a href="http://yoa.st/gasessions" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
195
+ 'type' => 'graph',
196
+ 'tab' => 'general',
197
+ ),
198
+ 'bounceRate' => array(
199
+ 'title' => __( 'Bounce rate', 'google-analytics-for-wordpress' ),
200
+ 'help' => __( 'Bounce Rate is the percentage of single-page sessions (i.e. sessions in which the person left your site from the entrance page without interacting with the page). <a href="http://yoa.st/gabounce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
201
+ 'data-percent' => true,
202
+ 'type' => 'graph',
203
+ 'tab' => 'general',
204
+ ),
205
+ 'source' => array(
206
+ 'title' => __( 'Traffic sources', 'google-analytics-for-wordpress' ),
207
+ 'help' => __( 'Every referral to a web site has an origin, or (traffic) source. Possible sources include: “google” (the name of a search engine), “facebook.com” (the name of a referring site), “spring_newsletter” (the name of one of your newsletters), and “direct” (users that typed your URL directly into their browser, or who had bookmarked your site). <a href="http://yoa.st/gabnce" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
208
+ 'type' => 'table',
209
+ 'columns' => array(
210
+ __( 'Sessions', 'google-analytics-for-wordpress' )
211
+ ),
212
+ 'tab' => 'dimensions',
213
+ ),
214
+ 'top_pageviews' => array(
215
+ 'title' => __( 'Popular pages', 'google-analytics-for-wordpress' ),
216
+ 'help' => __( 'Pages by url.', 'google-analytics-for-wordpress' ),
217
+ 'type' => 'table',
218
+ 'columns' => array(
219
+ __( 'Sessions', 'google-analytics-for-wordpress' )
220
+ ),
221
+ 'tab' => 'dimensions',
222
+ ),
223
+ 'top_countries' => array(
224
+ 'title' => __( 'Countries', 'google-analytics-for-wordpress' ),
225
+ 'help' => __( 'The country or territory from which visits originated. <a href="http://yoa.st/gacountry" target="_blank">[Learn more]</a>', 'google-analytics-for-wordpress' ),
226
+ 'type' => 'table',
227
+ 'columns' => array(
228
+ __( 'Sessions', 'google-analytics-for-wordpress' )
229
+ ),
230
+ 'tab' => 'dimensions',
231
+ ),
232
+ );
233
+ }
234
 
235
+ /**
236
+ * Validate the registered types of dashboards
237
+ *
238
+ * @param $types
239
+ *
240
+ * @return bool
241
+ */
242
+ private function validate_dashboard_types( $types ) {
243
+ $valid = true;
244
+
245
+ if ( is_array( $types ) ) {
246
+ foreach ( $types as $check_type ) {
247
+ if ( ! in_array( $check_type, $this->valid_metrics ) ) {
248
+ $valid = false;
 
249
  }
250
  }
 
 
251
  }
 
252
 
253
+ return $valid;
254
+ }
255
+ }
admin/dashboards/drivers/class-admin-dashboards-driver-generate.php CHANGED
@@ -1,121 +1,117 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Driver_Generate' ) ) {
4
-
5
- abstract class Yoast_GA_Dashboards_Driver_Generate {
6
-
7
- /**
8
- * @var string - Which type of data should be loaded
9
- */
10
- protected $graph_type;
11
-
12
- /**
13
- * @var string - For which period should the data be shown
14
- */
15
- protected $period;
16
-
17
- /**
18
- * @var string - The end date
19
- */
20
- protected $end_date;
21
-
22
- /**
23
- * @var string - The start date
24
- */
25
- protected $start_date;
26
-
27
- /**
28
- * Construct will set all values and generate the date for response
29
- */
30
- public function __construct() {
31
- $this->set_graph_type();
32
- $this->set_period();
33
- $this->set_end_date();
34
- $this->set_start_date();
35
- }
36
 
37
- /**
38
- * Getting graph_id from post and strip HTML-prefix graph- to get the type
39
- */
40
- protected function set_graph_type() {
41
- $graph_id = filter_input( INPUT_GET, 'graph_id' );
42
- $graph_type = str_replace( array( 'graph-', 'table-' ), '', $graph_id );
43
- $this->graph_type = $graph_type;
44
- }
45
 
46
- /**
47
- * Getting the period from post
48
- */
49
- protected function set_period() {
50
- $this->period = filter_input( INPUT_GET, 'period' );
51
- }
52
 
53
- /**
54
- * Setting the end date
55
- */
56
- protected function set_end_date() {
57
- $this->end_date = time();
58
- }
59
 
60
- /**
61
- * This method will set a start_date based on $this->period
62
- *
63
- * The values in dropdown, that will be mapped in strtotime
64
- * See: http://php.net/manual/en/datetime.formats.relative.php
65
- */
66
- protected function set_start_date() {
67
-
68
- switch ( $this->period ) {
69
- case 'lastweek' :
70
- $time = '-6 days';
71
- break;
72
- default:
73
- case 'lastmonth' :
74
- $time = '-1 month';
75
- break;
76
- }
77
-
78
- $start_date = strtotime( $time, $this->end_date );
79
-
80
- $this->start_date = $start_date;
81
  }
82
 
83
- /**
84
- * Getting the saved Google data
85
- *
86
- * @return array
87
- */
88
- protected function get_google_data() {
89
 
90
- $response = Yoast_GA_Dashboards_Data::get( $this->graph_type );
 
91
 
92
- if ( array_key_exists( 'body', $response['value'] ) ) {
93
- $return = $response['value']['body'];
94
- } else {
95
- $return = $response;
96
- }
 
97
 
98
- return $this->filter_google_data( $return );
99
- }
100
 
101
- /**
102
- * Check if given timestamp is in given period
103
- *
104
- * @param integer $timestamp
105
- *
106
- * @return bool
107
- */
108
- protected function is_date_in_period( $timestamp ) {
109
- return ( $timestamp >= $this->start_date && $timestamp <= $this->end_date );
110
  }
111
 
112
- /**
113
- * Should always be available
114
- *
115
- * @return mixed
116
- */
117
- abstract public function get_json();
118
 
 
 
 
 
 
 
 
 
 
119
  }
120
 
121
- }
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ abstract class Yoast_GA_Dashboards_Driver_Generate {
4
+
5
+ /**
6
+ * @var string - Which type of data should be loaded
7
+ */
8
+ protected $graph_type;
9
+
10
+ /**
11
+ * @var string - For which period should the data be shown
12
+ */
13
+ protected $period;
14
+
15
+ /**
16
+ * @var string - The end date
17
+ */
18
+ protected $end_date;
19
+
20
+ /**
21
+ * @var string - The start date
22
+ */
23
+ protected $start_date;
24
+
25
+ /**
26
+ * Construct will set all values and generate the date for response
27
+ */
28
+ public function __construct() {
29
+ $this->set_graph_type();
30
+ $this->set_period();
31
+ $this->set_end_date();
32
+ $this->set_start_date();
33
+ }
 
 
34
 
35
+ /**
36
+ * Getting graph_id from post and strip HTML-prefix graph- to get the type
37
+ */
38
+ protected function set_graph_type() {
39
+ $graph_id = filter_input( INPUT_GET, 'graph_id' );
40
+ $graph_type = str_replace( array( 'graph-', 'table-' ), '', $graph_id );
41
+ $this->graph_type = $graph_type;
42
+ }
43
 
44
+ /**
45
+ * Getting the period from post
46
+ */
47
+ protected function set_period() {
48
+ $this->period = filter_input( INPUT_GET, 'period' );
49
+ }
50
 
51
+ /**
52
+ * Setting the end date
53
+ */
54
+ protected function set_end_date() {
55
+ $this->end_date = time();
56
+ }
57
 
58
+ /**
59
+ * This method will set a start_date based on $this->period
60
+ *
61
+ * The values in dropdown, that will be mapped in strtotime
62
+ * See: http://php.net/manual/en/datetime.formats.relative.php
63
+ */
64
+ protected function set_start_date() {
65
+
66
+ switch ( $this->period ) {
67
+ case 'lastweek' :
68
+ $time = '-6 days';
69
+ break;
70
+ default:
71
+ case 'lastmonth' :
72
+ $time = '-1 month';
73
+ break;
 
 
 
 
 
74
  }
75
 
76
+ $start_date = strtotime( $time, $this->end_date );
 
 
 
 
 
77
 
78
+ $this->start_date = $start_date;
79
+ }
80
 
81
+ /**
82
+ * Getting the saved Google data
83
+ *
84
+ * @return array
85
+ */
86
+ protected function get_google_data() {
87
 
88
+ $response = Yoast_GA_Dashboards_Data::get( $this->graph_type );
 
89
 
90
+ if ( $response != array() && array_key_exists( 'body', $response['value'] ) ) {
91
+ $return = $response['value']['body'];
92
+ } else {
93
+ $return = $response;
 
 
 
 
 
94
  }
95
 
96
+ return $this->filter_google_data( $return );
97
+ }
 
 
 
 
98
 
99
+ /**
100
+ * Check if given timestamp is in given period
101
+ *
102
+ * @param integer $timestamp
103
+ *
104
+ * @return bool
105
+ */
106
+ protected function is_date_in_period( $timestamp ) {
107
+ return ( $timestamp >= $this->start_date && $timestamp <= $this->end_date );
108
  }
109
 
110
+ /**
111
+ * Should always be available
112
+ *
113
+ * @return mixed
114
+ */
115
+ abstract public function get_json();
116
+
117
+ }
admin/dashboards/drivers/class-admin-dashboards-driver.php CHANGED
@@ -1,80 +1,77 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Driver' ) ) {
4
 
5
- abstract class Yoast_GA_Dashboards_Driver {
 
 
 
 
 
6
 
7
- /**
8
- * Container for holding set dashboards
9
- *
10
- * @var array
11
- */
12
- protected $dashboards = array();
13
-
14
- /**
15
- * This will initialize the AJAX request
16
- */
17
- public function __construct() {
18
- $this->initialize_ajax();
19
- }
20
 
21
- /**
22
- * Method which will be called by AJAX
23
- *
24
- * Will echo json for graph
25
- */
26
- public function get_ajax_data() {
27
- check_ajax_referer( 'yoast-ga-dashboard-nonce', '_ajax_nonce' );
28
 
29
- $generator = $this->get_dashboard_generate_object();
30
- $json = $generator->get_json();
31
 
32
- echo $json;
33
- die();
34
- }
35
-
36
- /**
37
- * Register a dashboard with settings.
38
- *
39
- * Dashboard can contain multiple dashboard-types. If so, $values shouldn't be passed and $dashboard argument
40
- * should be key->value, key = dashboard and value should contain the values
41
- *
42
- * Given arguments will be marge with objects property dashboards
43
- *
44
- * @param mixed $dashboard
45
- * @param mixed $values
46
- */
47
- public function register( $dashboard, $values = false ) {
48
 
49
- if ( ! is_array( $dashboard ) ) {
50
- $dashboard = array( $dashboard => $values );
51
- }
 
 
 
 
 
 
 
 
 
52
 
53
- $this->dashboards = array_merge( $this->dashboards, $dashboard );
 
54
  }
55
 
56
- /**
57
- * Giving the dashboardname to show
58
- *
59
- * @param $dashboard
60
- */
61
- public function display( $dashboard ) {
62
- $settings = $this->dashboards[ $dashboard ];
63
- require dirname( GAWP_FILE ) . '/admin/dashboards/views/' . $this->dashboard_type . '.php';
64
- }
65
-
66
- /**
67
- * Setting hook for doing ajax request
68
- */
69
- protected function initialize_ajax() {
70
- add_action( $this->ajax_hook, array( $this, 'get_ajax_data' ) );
71
- }
72
 
73
- /**
74
- * This method should always be available
75
- * @return mixed
76
- */
77
- abstract protected function get_dashboard_generate_object();
 
 
 
 
78
 
 
 
 
 
 
79
  }
80
- }
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ abstract class Yoast_GA_Dashboards_Driver {
4
 
5
+ /**
6
+ * Container for holding set dashboards
7
+ *
8
+ * @var array
9
+ */
10
+ protected $dashboards = array();
11
 
12
+ /**
13
+ * This will initialize the AJAX request
14
+ */
15
+ public function __construct() {
16
+ $this->initialize_ajax();
17
+ }
 
 
 
 
 
 
 
18
 
19
+ /**
20
+ * Method which will be called by AJAX
21
+ *
22
+ * Will echo json for graph
23
+ */
24
+ public function get_ajax_data() {
25
+ check_ajax_referer( 'yoast-ga-dashboard-nonce', '_ajax_nonce' );
26
 
27
+ $generator = $this->get_dashboard_generate_object();
28
+ $json = $generator->get_json();
29
 
30
+ echo $json;
31
+ die();
32
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ /**
35
+ * Register a dashboard with settings.
36
+ *
37
+ * Dashboard can contain multiple dashboard-types. If so, $values shouldn't be passed and $dashboard argument
38
+ * should be key->value, key = dashboard and value should contain the values
39
+ *
40
+ * Given arguments will be marge with objects property dashboards
41
+ *
42
+ * @param mixed $dashboard
43
+ * @param mixed $values
44
+ */
45
+ public function register( $dashboard, $values = false ) {
46
 
47
+ if ( ! is_array( $dashboard ) ) {
48
+ $dashboard = array( $dashboard => $values );
49
  }
50
 
51
+ $this->dashboards = array_merge( $this->dashboards, $dashboard );
52
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
+ /**
55
+ * Giving the dashboardname to show
56
+ *
57
+ * @param $dashboard
58
+ */
59
+ public function display( $dashboard ) {
60
+ $settings = $this->dashboards[$dashboard];
61
+ require dirname( GAWP_FILE ) . '/admin/dashboards/views/' . $this->dashboard_type . '.php';
62
+ }
63
 
64
+ /**
65
+ * Setting hook for doing ajax request
66
+ */
67
+ protected function initialize_ajax() {
68
+ add_action( $this->ajax_hook, array( $this, 'get_ajax_data' ) );
69
  }
70
+
71
+ /**
72
+ * This method should always be available
73
+ * @return mixed
74
+ */
75
+ abstract protected function get_dashboard_generate_object();
76
+
77
+ }
admin/dashboards/drivers/class-admin-dashboards-graph-generate.php CHANGED
@@ -1,149 +1,147 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Graph_Generate' ) ) {
4
-
5
- class Yoast_GA_Dashboards_Graph_Generate extends Yoast_GA_Dashboards_Driver_Generate {
6
-
7
- /**
8
- * The field that will be used for displaying on x-axis. Mostly it will be the j (day in month)
9
- *
10
- * See: http://nl3.php.net/manual/en/function.date.php under 'format'
11
- *
12
- * @var string
13
- */
14
- private $date_field = 'j';
15
-
16
- /**
17
- * @var array - Storage for $data
18
- */
19
- private $data = array();
20
-
21
- /**
22
- * Storage for mapping
23
- *
24
- * @var array
25
- */
26
- private $mapping = array(
27
- 'x' => array(),
28
- 'hover' => array(),
29
- );
30
-
31
- /**
32
- * Construct will set all values and generate the date for response
33
- */
34
- public function __construct() {
35
- parent::__construct();
36
-
37
- $this->set_date_field();
 
38
 
39
- $this->generate();
40
- }
 
 
 
 
 
 
 
 
41
 
42
- /**
43
- * Putting $this->data and $this->mapping and give them back as a json encoded string
44
- *
45
- * @return string
46
- */
47
- public function get_json() {
48
- $return = array(
49
- 'data' => $this->data,
50
- 'mapping' => $this->mapping,
51
- );
52
-
53
- return json_encode( $return );
54
- }
55
 
56
- /**
57
- * Filtering the current data to eliminate all values which are not in given period
58
- *
59
- * @param integer $google_data
60
- *
61
- * @return integer
62
- */
63
- protected function filter_google_data( $google_data ) {
64
-
65
- foreach ( $google_data['value'] AS $unix_timestamp => $value ) {
66
- if ( $this->is_date_in_period( $unix_timestamp ) ) {
67
- $return[$unix_timestamp] = $value;
68
- }
69
  }
70
-
71
- return $return;
72
  }
73
 
74
- /**
75
- * Which field should be taken from timestamp. Most cases J will be good
76
- */
77
- private function set_date_field() {
78
- switch ( $this->period ) {
79
- default:
80
- case 'lastweek' :
81
- case 'lastmonth' :
82
- $date_field = 'j';
83
- break;
84
- }
85
 
86
- $this->date_field = $date_field;
 
 
 
 
 
 
 
 
 
87
  }
88
 
89
- /**
90
- * Generate the data for the frontend based on the $google_data
91
- */
92
- private function generate() {
93
 
94
- $google_data = $this->get_google_data();
 
 
 
95
 
96
- foreach ( $google_data AS $timestamp => $value ) {
97
- $this->add_data( $value );
98
- $this->add_x_mapping( $timestamp );
99
- $this->add_hover_mapping( $timestamp, $value );
100
- }
101
 
102
- $this->mapping['x'] = array_filter($this->mapping['x']);
 
 
 
103
  }
104
 
105
- /**
106
- * Adding value to data property
107
- *
108
- * x is position on x-axis, always starting from 0
109
- * y is the value of that point.
110
- *
111
- * @param integer $value
112
- */
113
- private function add_data( $value ) {
114
- static $current_x = 0;
115
-
116
- $this->data[] = array(
117
- 'x' => $current_x,
118
- 'y' => $value,
119
- );
120
-
121
- $current_x++;
122
- }
123
 
124
- /**
125
- * Add date field to the x-mapping
126
- *
127
- * Key will be auto numbered by PHP, starting with 0, the key will always point to the the x in x-axis
128
- * The value will be always the value that should be displayed.
129
- *
130
- * @param integer $timestamp
131
- */
132
- private function add_x_mapping( $timestamp ) {
133
-
134
- $is_monday = ( 'Mon' === date( 'D', $timestamp ) );
135
- $this->mapping['x'][] = $is_monday ? date( $this->date_field . ' M', $timestamp ) : null;
136
- }
 
 
137
 
138
- /**
139
- * Add date field to the hover-mapping
140
- *
141
- * @param integer $timestamp
142
- * @param integer $value
143
- */
144
- private function add_hover_mapping( $timestamp, $value ) {
145
- $this->mapping['hover'][] = date_i18n( 'l ' . $this->date_field . ' M', $timestamp ) . ': ' . $value;
146
- }
 
 
 
 
 
 
 
147
 
 
 
 
 
 
 
 
 
148
  }
 
149
  }
 
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Graph_Generate extends Yoast_GA_Dashboards_Driver_Generate {
4
+
5
+ /**
6
+ * The field that will be used for displaying on x-axis. Mostly it will be the j (day in month)
7
+ *
8
+ * See: http://nl3.php.net/manual/en/function.date.php under 'format'
9
+ *
10
+ * @var string
11
+ */
12
+ private $date_field = 'j';
13
+
14
+ /**
15
+ * @var array - Storage for $data
16
+ */
17
+ private $data = array();
18
+
19
+ /**
20
+ * Storage for mapping
21
+ *
22
+ * @var array
23
+ */
24
+ private $mapping = array(
25
+ 'x' => array(),
26
+ 'hover' => array(),
27
+ );
28
+
29
+ /**
30
+ * Construct will set all values and generate the date for response
31
+ */
32
+ public function __construct() {
33
+ parent::__construct();
34
+
35
+ $this->set_date_field();
36
+
37
+ $this->generate();
38
+ }
39
 
40
+ /**
41
+ * Putting $this->data and $this->mapping and give them back as a json encoded string
42
+ *
43
+ * @return string
44
+ */
45
+ public function get_json() {
46
+ $return = array(
47
+ 'data' => $this->data,
48
+ 'mapping' => $this->mapping,
49
+ );
50
 
51
+ return json_encode( $return );
52
+ }
 
 
 
 
 
 
 
 
 
 
 
53
 
54
+ /**
55
+ * Filtering the current data to eliminate all values which are not in given period
56
+ *
57
+ * @param integer $google_data
58
+ *
59
+ * @return integer
60
+ */
61
+ protected function filter_google_data( $google_data ) {
62
+
63
+ foreach ( $google_data['value'] AS $unix_timestamp => $value ) {
64
+ if ( $this->is_date_in_period( $unix_timestamp ) ) {
65
+ $return[$unix_timestamp] = $value;
 
66
  }
 
 
67
  }
68
 
69
+ return $return;
70
+ }
 
 
 
 
 
 
 
 
 
71
 
72
+ /**
73
+ * Which field should be taken from timestamp. Most cases J will be good
74
+ */
75
+ private function set_date_field() {
76
+ switch ( $this->period ) {
77
+ default:
78
+ case 'lastweek' :
79
+ case 'lastmonth' :
80
+ $date_field = 'j';
81
+ break;
82
  }
83
 
84
+ $this->date_field = $date_field;
85
+ }
 
 
86
 
87
+ /**
88
+ * Generate the data for the frontend based on the $google_data
89
+ */
90
+ private function generate() {
91
 
92
+ $google_data = $this->get_google_data();
 
 
 
 
93
 
94
+ foreach ( $google_data AS $timestamp => $value ) {
95
+ $this->add_data( $value );
96
+ $this->add_x_mapping( $timestamp );
97
+ $this->add_hover_mapping( $timestamp, $value );
98
  }
99
 
100
+ $this->mapping['x'] = array_filter( $this->mapping['x'] );
101
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
 
103
+ /**
104
+ * Adding value to data property
105
+ *
106
+ * x is position on x-axis, always starting from 0
107
+ * y is the value of that point.
108
+ *
109
+ * @param integer $value
110
+ */
111
+ private function add_data( $value ) {
112
+ static $current_x = 0;
113
+
114
+ $this->data[] = array(
115
+ 'x' => $current_x,
116
+ 'y' => $value,
117
+ );
118
 
119
+ $current_x ++;
120
+ }
121
+
122
+ /**
123
+ * Add date field to the x-mapping
124
+ *
125
+ * Key will be auto numbered by PHP, starting with 0, the key will always point to the the x in x-axis
126
+ * The value will be always the value that should be displayed.
127
+ *
128
+ * @param integer $timestamp
129
+ */
130
+ private function add_x_mapping( $timestamp ) {
131
+
132
+ $is_monday = ( 'Mon' === date( 'D', $timestamp ) );
133
+ $this->mapping['x'][] = $is_monday ? date( $this->date_field . ' M', $timestamp ) : null;
134
+ }
135
 
136
+ /**
137
+ * Add date field to the hover-mapping
138
+ *
139
+ * @param integer $timestamp
140
+ * @param integer $value
141
+ */
142
+ private function add_hover_mapping( $timestamp, $value ) {
143
+ $this->mapping['hover'][] = date_i18n( 'l ' . $this->date_field . ' M', $timestamp ) . ': ' . number_format_i18n( $value, 0 );
144
  }
145
+
146
  }
147
+
admin/dashboards/drivers/class-admin-dashboards-graph.php CHANGED
@@ -1,27 +1,24 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Graph' ) ) {
4
 
5
- class Yoast_GA_Dashboards_Graph extends Yoast_GA_Dashboards_Driver {
 
 
 
6
 
7
- /**
8
- * @var string The type of dashboard wherefore this object is created
9
- */
10
- protected $dashboard_type = 'graph';
11
-
12
- /**
13
- * @var string The hook for ajax, when this is called the hook will be executed
14
- */
15
- protected $ajax_hook = 'wp_ajax_yoast_dashboard_graphdata';
16
-
17
- /**
18
- * The object that handles the response and generates the content for dashboard
19
- *
20
- * @return Yoast_GA_Dashboards_Graph_Generate
21
- */
22
- protected function get_dashboard_generate_object() {
23
- return new Yoast_GA_Dashboards_Graph_Generate();
24
- }
25
 
 
 
 
 
 
 
 
26
  }
 
27
  }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Graph extends Yoast_GA_Dashboards_Driver {
4
 
5
+ /**
6
+ * @var string The type of dashboard wherefore this object is created
7
+ */
8
+ protected $dashboard_type = 'graph';
9
 
10
+ /**
11
+ * @var string The hook for ajax, when this is called the hook will be executed
12
+ */
13
+ protected $ajax_hook = 'wp_ajax_yoast_dashboard_graphdata';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ /**
16
+ * The object that handles the response and generates the content for dashboard
17
+ *
18
+ * @return Yoast_GA_Dashboards_Graph_Generate
19
+ */
20
+ protected function get_dashboard_generate_object() {
21
+ return new Yoast_GA_Dashboards_Graph_Generate();
22
  }
23
+
24
  }
admin/dashboards/drivers/class-admin-dashboards-table-generate.php CHANGED
@@ -1,70 +1,67 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Table_Generate' ) ) {
4
 
5
- class Yoast_GA_Dashboards_Table_Generate extends Yoast_GA_Dashboards_Driver_Generate {
 
 
 
6
 
7
- /**
8
- * @var string - The ID of requested dimension
9
- */
10
- protected $dimension_id;
 
11
 
12
- /**
13
- * Construct will set all values and generate the date for response
14
- */
15
- public function __construct() {
16
- parent::__construct();
17
 
18
- $this->set_dimension_id();
19
-
20
- $this->generate();
21
- }
22
-
23
- /**
24
- * Putting $this->data and $this->mapping and give them back as a json encoded string
25
- *
26
- * @return string
27
- */
28
- public function get_json() {
29
- $return = array(
30
- 'data' => $this->data,
31
- );
32
 
33
- return json_encode( $return );
34
- }
 
 
 
 
 
 
 
35
 
36
- /**
37
- * Filtering the current data to eliminate all values which are not in given period
38
- *
39
- * @param integer $google_data
40
- *
41
- * @return integer
42
- */
43
- protected function filter_google_data( $google_data ) {
44
- return $google_data['value'];
45
- }
46
 
47
- /**
48
- * Setting the dimension_id for current request. Based on dimension_id the graph_type will be set, this to
49
- * handle the request correctly
50
- */
51
- private function set_dimension_id() {
52
- $this->dimension_id = filter_input( INPUT_GET, 'dimension_id' );
 
 
 
 
53
 
54
- if ( ! empty( $this->dimension_id ) ) {
55
- $this->graph_type = 'ga:dimension' . $this->dimension_id;
56
- } else {
57
- $this->graph_type = $this->graph_type;
58
- }
59
- }
60
 
61
- /**
62
- * Generate the data for the frontend based on the $google_data
63
- */
64
- private function generate() {
65
- $google_data = $this->get_google_data();
66
- $this->data = array_values( $google_data );
67
  }
 
68
 
 
 
 
 
 
 
69
  }
 
70
  }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Table_Generate extends Yoast_GA_Dashboards_Driver_Generate {
4
 
5
+ /**
6
+ * @var string - The ID of requested dimension
7
+ */
8
+ protected $dimension_id;
9
 
10
+ /**
11
+ * Construct will set all values and generate the date for response
12
+ */
13
+ public function __construct() {
14
+ parent::__construct();
15
 
16
+ $this->set_dimension_id();
 
 
 
 
17
 
18
+ $this->generate();
19
+ }
 
 
 
 
 
 
 
 
 
 
 
 
20
 
21
+ /**
22
+ * Putting $this->data and $this->mapping and give them back as a json encoded string
23
+ *
24
+ * @return string
25
+ */
26
+ public function get_json() {
27
+ $return = array(
28
+ 'data' => $this->data,
29
+ );
30
 
31
+ return json_encode( $return );
32
+ }
 
 
 
 
 
 
 
 
33
 
34
+ /**
35
+ * Filtering the current data to eliminate all values which are not in given period
36
+ *
37
+ * @param integer $google_data
38
+ *
39
+ * @return integer
40
+ */
41
+ protected function filter_google_data( $google_data ) {
42
+ return $google_data['value'];
43
+ }
44
 
45
+ /**
46
+ * Setting the dimension_id for current request. Based on dimension_id the graph_type will be set, this to
47
+ * handle the request correctly
48
+ */
49
+ private function set_dimension_id() {
50
+ $this->dimension_id = filter_input( INPUT_GET, 'dimension_id' );
51
 
52
+ if ( ! empty( $this->dimension_id ) ) {
53
+ $this->graph_type = 'ga:dimension' . $this->dimension_id;
54
+ } else {
55
+ $this->graph_type = $this->graph_type;
 
 
56
  }
57
+ }
58
 
59
+ /**
60
+ * Generate the data for the frontend based on the $google_data
61
+ */
62
+ private function generate() {
63
+ $google_data = $this->get_google_data();
64
+ $this->data = array_values( $google_data );
65
  }
66
+
67
  }
admin/dashboards/drivers/class-admin-dashboards-table.php CHANGED
@@ -1,27 +1,24 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Dashboards_Table' ) ) {
4
 
5
- class Yoast_GA_Dashboards_Table extends Yoast_GA_Dashboards_Driver {
 
 
 
6
 
7
- /**
8
- * @var string The type of dashboard wherefore this object is created
9
- */
10
- protected $dashboard_type = 'table';
11
-
12
- /**
13
- * @var string The hook for ajax, when this is called the hook will be executed
14
- */
15
- protected $ajax_hook = 'wp_ajax_yoast_dashboard_tabledata';
16
-
17
- /**
18
- * The object that handles the response and generates the content for dashboard
19
- *
20
- * @return Yoast_GA_Dashboards_Table_Generate
21
- */
22
- protected function get_dashboard_generate_object() {
23
- return new Yoast_GA_Dashboards_Table_Generate();
24
- }
25
 
 
 
 
 
 
 
 
26
  }
 
27
  }
1
  <?php
2
 
3
+ class Yoast_GA_Dashboards_Table extends Yoast_GA_Dashboards_Driver {
4
 
5
+ /**
6
+ * @var string The type of dashboard wherefore this object is created
7
+ */
8
+ protected $dashboard_type = 'table';
9
 
10
+ /**
11
+ * @var string The hook for ajax, when this is called the hook will be executed
12
+ */
13
+ protected $ajax_hook = 'wp_ajax_yoast_dashboard_tabledata';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
+ /**
16
+ * The object that handles the response and generates the content for dashboard
17
+ *
18
+ * @return Yoast_GA_Dashboards_Table_Generate
19
+ */
20
+ protected function get_dashboard_generate_object() {
21
+ return new Yoast_GA_Dashboards_Table_Generate();
22
  }
23
+
24
  }
admin/license-manager/composer.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name" : "yoast/license-manager",
3
+ "description": "Yoast License Manager.",
4
+ "keywords" : ["wordpress"],
5
+ "homepage" : "https://github.com/Yoast/License-Manager",
6
+ "license" : "GPL-2.0+",
7
+ "authors" : [
8
+ {
9
+ "name" : "Team Yoast",
10
+ "email" : "support@yoast.com",
11
+ "homepage": "https://yoast.com"
12
+ }
13
+ ],
14
+ "support" : {
15
+ "issues": "https://github.com/Yoast/License-Manager/issues"
16
+ },
17
+ "autoload" : {
18
+ "classmap": [
19
+ "class-api-request.php",
20
+ "class-license-manager.php",
21
+ "class-plugin-license-manager.php",
22
+ "class-plugin-update-manager.php",
23
+ "class-product.php",
24
+ "class-theme-license-manager.php",
25
+ "class-theme-update-manager.php",
26
+ "class-update-manager.php"
27
+ ]
28
+ }
29
+ }
admin/pages/dashboard.php CHANGED
@@ -7,7 +7,7 @@ $tracking_code = $options_class->get_tracking_code();
7
 
8
  echo $yoast_ga_admin->content_head();
9
  ?>
10
- <h2 id="yoast_ga_title"><?php echo __( 'Yoast Google Analytics: ', 'google-analytics-for-wordpress' ) . __( 'Dashboard', 'google-analytics-for-wordpress' ); ?></h2>
11
 
12
  <h2 class="nav-tab-wrapper" id="ga-tabs">
13
  <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'Overview', 'google-analytics-for-wordpress' ); ?></a>
7
 
8
  echo $yoast_ga_admin->content_head();
9
  ?>
10
+ <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by Yoast: ', 'google-analytics-for-wordpress' ) . __( 'Dashboard', 'google-analytics-for-wordpress' ); ?> <?php do_action( 'yst_ga_dashboard_title' ); ?></h2>
11
 
12
  <h2 class="nav-tab-wrapper" id="ga-tabs">
13
  <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'Overview', 'google-analytics-for-wordpress' ); ?></a>
admin/pages/extensions.php CHANGED
@@ -7,7 +7,7 @@ $has_extensions = false;
7
 
8
  $extensions = $yoast_ga_admin->get_extensions();
9
  ?>
10
- <h2 id="yoast_ga_title"><?php echo __( 'Yoast Google Analytics: ', 'google-analytics-for-wordpress' ) . __( 'Extensions', 'google-analytics-for-wordpress' ); ?></h2>
11
 
12
  <h2 class="nav-tab-wrapper" id="ga-tabs">
13
  <a class="nav-tab active" id="extensions-tab" href="#top#extensions"><?php _e( 'Extensions', 'google-analytics-for-wordpress' ); ?></a>
@@ -55,7 +55,7 @@ $extensions = $yoast_ga_admin->get_extensions();
55
  <div id="licenses" class="wpseotab gatab">
56
  <?php
57
  if ( ! $has_extensions ) {
58
- echo '<p>' . __( 'You have not installed any extensions for Yoast Google Analytics, so there are no licenses to activate.', 'google-analytics-for-wordpress' ) . '</p>';
59
  } else {
60
  do_action( 'yst_ga_show_license_form' );
61
  }
7
 
8
  $extensions = $yoast_ga_admin->get_extensions();
9
  ?>
10
+ <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by Yoast: ', 'google-analytics-for-wordpress' ) . __( 'Extensions', 'google-analytics-for-wordpress' ); ?></h2>
11
 
12
  <h2 class="nav-tab-wrapper" id="ga-tabs">
13
  <a class="nav-tab active" id="extensions-tab" href="#top#extensions"><?php _e( 'Extensions', 'google-analytics-for-wordpress' ); ?></a>
55
  <div id="licenses" class="wpseotab gatab">
56
  <?php
57
  if ( ! $has_extensions ) {
58
+ echo '<p>' . __( 'You have not installed any extensions for Google Analytics by Yoast, so there are no licenses to activate.', 'google-analytics-for-wordpress' ) . '</p>';
59
  } else {
60
  do_action( 'yst_ga_show_license_form' );
61
  }
admin/pages/settings.php CHANGED
@@ -3,7 +3,7 @@ global $yoast_ga_admin;
3
 
4
  echo $yoast_ga_admin->content_head();
5
  ?>
6
- <h2 id="yoast_ga_title"><?php echo __( 'Yoast Google Analytics: ', 'google-analytics-for-wordpress' ) . __( 'Settings', 'google-analytics-for-wordpress' ); ?></h2>
7
 
8
  <?php
9
  settings_errors( 'yoast_google_analytics' );
@@ -13,7 +13,7 @@ settings_errors( 'yoast_google_analytics' );
13
  <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'google-analytics-for-wordpress' ); ?></a>
14
  <a class="nav-tab" id="universal-tab" href="#top#universal"><?php _e( 'Universal', 'google-analytics-for-wordpress' ); ?></a>
15
  <a class="nav-tab" id="advanced-tab" href="#top#advanced"><?php _e( 'Advanced', 'google-analytics-for-wordpress' ); ?></a>
16
- <a class="nav-tab" id="customdimensions-tab" href="#top#customdimensions"><?php _e( 'Custom dimensions', 'google-analytics-for-wordpress' ); ?></a>
17
  <?php do_action( 'yst_ga_custom_tabs-tab' ); ?>
18
  <a class="nav-tab" id="debugmode-tab" href="#top#debugmode"><?php _e( 'Debug mode', 'google-analytics-for-wordpress' ); ?></a>
19
  </h2>
@@ -62,9 +62,11 @@ echo Yoast_GA_Admin_Form::create_form( 'settings' );
62
  echo '</div>';
63
 
64
  echo '<div id="oauth_code" class="ga-form ga-form-input">';
65
- echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">' . __( 'Paste your Google code and press return', 'google-analytics-for-wordpress' ) . ':</label>';
66
  echo Yoast_GA_Admin_Form::input( 'text', null, 'google_auth_code', null, null );
67
 
 
 
68
  echo '</div>';
69
  } else {
70
  echo '<h3>' . __( 'Cannot connect to Google', 'google-analytics-for-wordpress' ) . '</h3>';
@@ -87,17 +89,18 @@ echo Yoast_GA_Admin_Form::create_form( 'settings' );
87
  ?>
88
  <div class="clear"><br /></div>
89
  <?php
90
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Track outbound click & downloads', 'google-analytics-for-wordpress' ), 'track_outbound', null, __( 'Clicks &amp; downloads will be tracked as events, you can find these under Content &raquo; Event Tracking in your Google Analytics reports.', 'google-analytics-for-wordpress' ) );
91
  echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow tracking of anonymous data', 'google-analytics-for-wordpress' ), 'anonymous_data', null, __( 'By allowing us to track anonymous data we can better help you, because we know with which WordPress configurations, themes and plugins we should test. No personal data will be submitted.', 'google-analytics-for-wordpress' ) );
92
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Anonymize IP\'s', 'google-analytics-for-wordpress' ), 'anonymize_ips', null, sprintf( __( 'This adds <code>%1$s _anonymizeIp%2$s</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.', 'google-analytics-for-wordpress' ), '<a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gat.html#_gat._anonymizeIp" target="_blank">', '</a>' ) );
93
  echo Yoast_GA_Admin_Form::select( 'Ignore users', 'ignore_users', $yoast_ga_admin->get_userroles(), __( 'Users of the role you select will be ignored, so if you select Editor, all Editors will be ignored.', 'google-analytics-for-wordpress' ), true );
 
94
  ?>
95
  </div>
96
  <div id="universal" class="gatab">
97
  <?php
98
  echo '<h2>' . __( 'Universal settings', 'google-analytics-for-wordpress' ) . '</h2>';
99
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable Universal tracking', 'google-analytics-for-wordpress' ), 'enable_universal', null, sprintf( __( 'First enable Universal tracking in your Google Analytics account. How to do that, please read %1$sthis guide%2$s to learn how to do that.', 'google-analytics-for-wordpress' ), '<a href="http://kb.yoast.com/article/125-universal-analytics#utm_medium=kb-link&utm_source=gawp-config&utm_campaign=wpgaplugin" target="_blank">', '</a>' ) );
100
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable Demographics and Interest Reports', 'google-analytics-for-wordpress' ), 'demographics', null, sprintf( __( 'You have to enable the Demographics in Google Analytics before you can see the tracking data. We have a doc in our %1$sknowlegde base%2$s about this feature.', 'google-analytics-for-wordpress' ), '<a href="http://kb.yoast.com/article/154-enable-demographics-and-interests-report-in-google-analytics/#utm_medium=kb-link&utm_source=gawp-config&utm_campaign=wpgaplugin" target="_blank">', '</a>' ) );
101
  ?>
102
  </div>
103
  <div id="advanced" class="gatab">
@@ -106,15 +109,15 @@ echo Yoast_GA_Admin_Form::create_form( 'settings' );
106
  echo Yoast_GA_Admin_Form::select( __( 'Track downloads as', 'google-analytics-for-wordpress' ), 'track_download_as', $yoast_ga_admin->track_download_types(), __( 'Not recommended, as this would skew your statistics, but it does make it possible to track downloads as goals.', 'google-analytics-for-wordpress' ) );
107
  echo Yoast_GA_Admin_Form::input( 'text', __( 'Extensions of files to track as downloads', 'google-analytics-for-wordpress' ), 'extensions_of_files', null, 'Please separate extensions using commas' );
108
  echo Yoast_GA_Admin_Form::select( __( 'Track full URL of outbound clicks or just the domain', 'google-analytics-for-wordpress' ), 'track_full_url', $yoast_ga_admin->get_track_full_url() );
109
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Subdomain tracking', 'google-analytics-for-wordpress' ), 'subdomain_tracking', null, __( 'This allows you to set the domain that\'s set by <code>setDomainName</code> for tracking subdomains, if empty this will not be set.', 'google-analytics-for-wordpress' ) );
110
 
111
- echo Yoast_GA_Admin_Form::input( 'text', __( 'Set path for internal links to track as outbound links', 'google-analytics-for-wordpress' ), 'track_internal_as_outbound', null, '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>' );
112
  echo Yoast_GA_Admin_Form::input( 'text', __( 'Label for those links', 'google-analytics-for-wordpress' ), 'track_internal_as_label', null, '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".' );
113
 
114
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Tag links in RSS feed with campaign variables', 'google-analytics-for-wordpress' ), 'tag_links_in_rss', null, __( 'Do not use this feature if you use FeedBurner, as FeedBurner can do this automatically, and better than this plugin can. Check <a href="https://support.google.com/feedburner/answer/165769?hl=en&amp;ref_topic=13075" target="_blank">this help page</a> for info on how to enable this feature in FeedBurner.', 'google-analytics-for-wordpress' ) );
115
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow anchor', 'google-analytics-for-wordpress' ), 'allow_anchor', null, sprintf( __( 'This adds a <code>%1$s_setAllowAnchor%2$s</code> call to your tracking code, and makes RSS link tagging use a # as well.', 'google-analytics-for-wordpress' ), '<a href="http://code.google.com/apis/analytics/docs/gaJSApiCampaignTracking.html#_gat.GA_Tracker_._setAllowAnchor" target="_blank">', '</a>' ) );
116
- echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Add <code>_setAllowLinker</code>', 'google-analytics-for-wordpress' ), 'add_allow_linker', null, sprintf( __( 'This adds a <code>%1$s_setAllowLinker%2$s</code> call to your tracking code, allowing you to use <code>_link</code> and related functions.', 'google-analytics-for-wordpress' ), '<a href="http://code.google.com/apis/analytics/docs/gaJS/gaJSApiDomainDirectory.html#_gat.GA_Tracker_._setAllowLinker" target="_blank">', '</a>' ) );
117
- echo Yoast_GA_Admin_Form::textarea( 'Custom code', 'custom_code', __( 'Not for the average user: this allows you to add a line of code, to be added before the <code>trackPageview</code> call.', 'google-analytics-for-wordpress' ) );
118
 
119
  do_action( 'yst_ga_advanced-tab' );
120
  ?>
@@ -128,11 +131,11 @@ echo Yoast_GA_Admin_Form::create_form( 'settings' );
128
  <?php do_action( 'yst_ga_custom_tabs-content' ); ?>
129
  <div id="debugmode" class="gatab">
130
  <?php
131
- echo '<h2>' . __( 'Debug settings', 'google-analytics-for-wordpress' ) . '</h2>';
132
 
133
  echo '<div id="ga-promote">';
134
  echo '<p class="ga-topdescription">' . __( 'If you want to confirm that tracking on your blog is working as it should, enable this option and check the console of your browser. Be absolutely sure to disable debugging afterwards, as it is slower than normal tracking.', 'google-analytics-for-wordpress' ) . '</p>';
135
- echo '<p class="ga-topdescription"><strong>' . __( 'Note', 'google-analytics-for-wordpress' ) . ':</strong> ' . __( 'the debugging scripts is only loaded for admins.', 'google-analytics-for-wordpress' ) . '</p>';
136
  echo '</div>';
137
  echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable debug mode', 'google-analytics-for-wordpress' ), 'debug_mode' );
138
  ?>
3
 
4
  echo $yoast_ga_admin->content_head();
5
  ?>
6
+ <h2 id="yoast_ga_title"><?php echo __( 'Google Analytics by Yoast: ', 'google-analytics-for-wordpress' ) . __( 'Settings', 'google-analytics-for-wordpress' ); ?></h2>
7
 
8
  <?php
9
  settings_errors( 'yoast_google_analytics' );
13
  <a class="nav-tab" id="general-tab" href="#top#general"><?php _e( 'General', 'google-analytics-for-wordpress' ); ?></a>
14
  <a class="nav-tab" id="universal-tab" href="#top#universal"><?php _e( 'Universal', 'google-analytics-for-wordpress' ); ?></a>
15
  <a class="nav-tab" id="advanced-tab" href="#top#advanced"><?php _e( 'Advanced', 'google-analytics-for-wordpress' ); ?></a>
16
+ <a class="nav-tab" id="customdimensions-tab" href="#top#customdimensions"><?php _e( 'Custom Dimensions', 'google-analytics-for-wordpress' ); ?></a>
17
  <?php do_action( 'yst_ga_custom_tabs-tab' ); ?>
18
  <a class="nav-tab" id="debugmode-tab" href="#top#debugmode"><?php _e( 'Debug mode', 'google-analytics-for-wordpress' ); ?></a>
19
  </h2>
62
  echo '</div>';
63
 
64
  echo '<div id="oauth_code" class="ga-form ga-form-input">';
65
+ echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle">' . __( 'Paste your Google code here', 'google-analytics-for-wordpress' ) . ':</label>';
66
  echo Yoast_GA_Admin_Form::input( 'text', null, 'google_auth_code', null, null );
67
 
68
+ echo '<label class="ga-form ga-form-text-label ga-form-label-left" id="yoast-ga-form-label-text-ga-authwithgoogle-submit">&nbsp;</label>';
69
+ echo '<div class="ga-form ga-form-input"><input type="submit" name="ga-form-settings" value="' . __('Save authentication code', 'google-analytics-for-wordpress') . '" class="button button-primary ga-form-submit" id="yoast-ga-form-submit-settings"></div>';
70
  echo '</div>';
71
  } else {
72
  echo '<h3>' . __( 'Cannot connect to Google', 'google-analytics-for-wordpress' ) . '</h3>';
89
  ?>
90
  <div class="clear"><br /></div>
91
  <?php
92
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Track outbound click and downloads', 'google-analytics-for-wordpress' ), 'track_outbound', null, __( 'Clicks and downloads will be tracked as events, you can find these under Content &#xBB; Event Tracking in your Google Analytics reports.', 'google-analytics-for-wordpress' ) );
93
  echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow tracking of anonymous data', 'google-analytics-for-wordpress' ), 'anonymous_data', null, __( 'By allowing us to track anonymous data we can better help you, because we know with which WordPress configurations, themes and plugins we should test. No personal data will be submitted.', 'google-analytics-for-wordpress' ) );
94
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Anonymize IPs', 'google-analytics-for-wordpress' ), 'anonymize_ips', null, sprintf( __( 'This adds %1$s, 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.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApi_gat?csw=1#_gat._anonymizeIp" target="_blank"><code>_anonymizeIp</code></a>' ) );
95
  echo Yoast_GA_Admin_Form::select( 'Ignore users', 'ignore_users', $yoast_ga_admin->get_userroles(), __( 'Users of the role you select will be ignored, so if you select Editor, all Editors will be ignored.', 'google-analytics-for-wordpress' ), true );
96
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Disable analytics dashboard', 'google-analytics-for-wordpress' ), 'dashboards_disabled', null, __( 'This will completely disable the dashboard and stop the plugin from fetching the latest analytics data.', 'google-analytics-for-wordpress' ) );
97
  ?>
98
  </div>
99
  <div id="universal" class="gatab">
100
  <?php
101
  echo '<h2>' . __( 'Universal settings', 'google-analytics-for-wordpress' ) . '</h2>';
102
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable Universal tracking', 'google-analytics-for-wordpress' ), 'enable_universal', null, sprintf( __( 'First enable Universal tracking in your Google Analytics account. Please read %1$sthis guide%2$s to learn how to do that.', 'google-analytics-for-wordpress' ), '<a href="http://kb.yoast.com/article/125-universal-analytics#utm_medium=kb-link&utm_source=gawp-config&utm_campaign=wpgaplugin" target="_blank">', '</a>' ) );
103
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable Demographics and Interest Reports', 'google-analytics-for-wordpress' ), 'demographics', null, sprintf( __( 'You have to enable the Demographics in Google Analytics before you can see the tracking data. We have a knowledge base article in our %1$sknowledge base%2$s about this feature.', 'google-analytics-for-wordpress' ), '<a href="http://kb.yoast.com/article/154-enable-demographics-and-interests-report-in-google-analytics/#utm_medium=kb-link&amp;utm_source=gawp-config&amp;utm_campaign=wpgaplugin" target="_blank">', '</a>' ) );
104
  ?>
105
  </div>
106
  <div id="advanced" class="gatab">
109
  echo Yoast_GA_Admin_Form::select( __( 'Track downloads as', 'google-analytics-for-wordpress' ), 'track_download_as', $yoast_ga_admin->track_download_types(), __( 'Not recommended, as this would skew your statistics, but it does make it possible to track downloads as goals.', 'google-analytics-for-wordpress' ) );
110
  echo Yoast_GA_Admin_Form::input( 'text', __( 'Extensions of files to track as downloads', 'google-analytics-for-wordpress' ), 'extensions_of_files', null, 'Please separate extensions using commas' );
111
  echo Yoast_GA_Admin_Form::select( __( 'Track full URL of outbound clicks or just the domain', 'google-analytics-for-wordpress' ), 'track_full_url', $yoast_ga_admin->get_track_full_url() );
112
+ echo Yoast_GA_Admin_Form::input( 'text', __( 'Subdomain tracking', 'google-analytics-for-wordpress' ), 'subdomain_tracking', null, sprintf( __( 'This allows you to set the domain that\'s set by %1$s for tracking subdomains.<br/>If empty, this will not be set.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiDomainDirectory#_gat.GA_Tracker_._setDomainName" target="_blank"><code>_setDomainName</code></a>' ) );
113
 
114
+ echo Yoast_GA_Admin_Form::input( 'text', __( 'Set path for internal links to track as outbound links', 'google-analytics-for-wordpress' ), 'track_internal_as_outbound', null, sprintf( __( 'If you want to track all internal links that begin with %1$s, enter %1$s in the box above. If you have multiple prefixes you can separate them with comma\'s: %2$s', 'google-analytics-for-wordpress' ), '<code>/out/</code>', '<code>/out/,/recommends/</code>' ) );
115
  echo Yoast_GA_Admin_Form::input( 'text', __( 'Label for those links', 'google-analytics-for-wordpress' ), 'track_internal_as_label', null, '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".' );
116
 
117
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Tag links in RSS feed with campaign variables', 'google-analytics-for-wordpress' ), 'tag_links_in_rss', null, __( 'Do not use this feature if you use FeedBurner, as FeedBurner can do this automatically and better than this plugin can. Check <a href="https://support.google.com/feedburner/answer/165769?hl=en&amp;ref_topic=13075" target="_blank">this help page</a> for info on how to enable this feature in FeedBurner.', 'google-analytics-for-wordpress' ) );
118
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Allow anchor', 'google-analytics-for-wordpress' ), 'allow_anchor', null , sprintf(__( 'This adds a %1$s call to your tracking code, and makes RSS link tagging use a %2$s as well.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiCampaignTracking?csw=1#_gat.GA_Tracker_._setAllowAnchor" target="_blank"><code>_setAllowAnchor</code></a>', '<code>#</code>' ));
119
+ echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Add <code>_setAllowLinker</code>', 'google-analytics-for-wordpress' ), 'add_allow_linker', null, sprintf( __( 'This adds a %1$s call to your tracking code, allowing you to use %2$s and related functions.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiDomainDirectory?csw=1#_gat.GA_Tracker_._setAllowLinker" target="_blank"><code>_setAllowLinker</code></a>', ' <code>_link</code>' ) );
120
+ echo Yoast_GA_Admin_Form::textarea( 'Custom code', 'custom_code', sprintf( __( 'Not for the average user: this allows you to add a line of code, to be added before the %1$s call.', 'google-analytics-for-wordpress' ), '<a href="https://developers.google.com/analytics/devguides/collection/gajs/methods/gaJSApiBasicConfiguration#_gat.GA_Tracker_._trackPageview" target="_blank"><code>_trackPageview</code></a>' ) );
121
 
122
  do_action( 'yst_ga_advanced-tab' );
123
  ?>
131
  <?php do_action( 'yst_ga_custom_tabs-content' ); ?>
132
  <div id="debugmode" class="gatab">
133
  <?php
134
+ echo '<h2>' . __( 'Debug', 'google-analytics-for-wordpress' ) . '</h2>';
135
 
136
  echo '<div id="ga-promote">';
137
  echo '<p class="ga-topdescription">' . __( 'If you want to confirm that tracking on your blog is working as it should, enable this option and check the console of your browser. Be absolutely sure to disable debugging afterwards, as it is slower than normal tracking.', 'google-analytics-for-wordpress' ) . '</p>';
138
+ echo '<p class="ga-topdescription">' . __( '<strong>Note</strong> the debugging is only loaded for administrators.', 'google-analytics-for-wordpress' ) . '</p>';
139
  echo '</div>';
140
  echo Yoast_GA_Admin_Form::input( 'checkbox', __( 'Enable debug mode', 'google-analytics-for-wordpress' ), 'debug_mode' );
141
  ?>
assets/js/yoast_ga_admin.js CHANGED
@@ -1,10 +1,28 @@
1
  function yst_popupwindow(url, w, h) {
 
2
  var left = (screen.width/2)-(w/2);
3
  var top = (screen.height/8);
4
  return window.open(url, '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
5
  }
6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  jQuery(document).ready(function() {
 
8
  jQuery('#ga-tabs').find('a').click(function() {
9
  jQuery('#ga-tabs').find('a').removeClass('nav-tab-active');
10
  jQuery('.gatab').removeClass('active');
@@ -33,27 +51,12 @@ jQuery(document).ready(function() {
33
  jQuery('#' + activeTab).addClass('active');
34
  jQuery('#' + activeTab + '-tab').addClass('nav-tab-active');
35
 
36
- function yst_ga_switch_manual() {
37
- if ( jQuery('#yoast-ga-form-checkbox-settings-manual_ua_code').is(':checked') ) {
38
- jQuery('#enter_ua').show();
39
- jQuery("#yoast-ga-form-select-settings-analytics_profile").prop('disabled', true).trigger("chosen:updated");
40
- jQuery("#yst_ga_authenticate").attr('disabled', true);
41
- jQuery('#oauth_code').hide();
42
- } else {
43
- jQuery('#enter_ua').hide();
44
- jQuery('#yoast-ga-form-text-settings-manual_ua_code_field').attr('value', '');
45
- jQuery("#yoast-ga-form-select-settings-analytics_profile").prop('disabled', false).trigger("chosen:updated");
46
- jQuery("#yst_ga_authenticate").attr('disabled', false);
47
- jQuery('#oauth_code').show();
48
- }
49
- }
50
-
51
  // Manually enter a UA code
52
- jQuery('#yoast-ga-form-checkbox-settings-manual_ua_code').click( function() { yst_ga_switch_manual(); } );
53
  yst_ga_switch_manual();
54
 
55
  jQuery('#oauth_code').hide();
56
- jQuery("#yst_ga_authenticate").click( function() {
57
  jQuery('#oauth_code').show();
58
  Focusable.setFocus(jQuery('#oauth_code'), {hideOnESC:true});
59
  jQuery('#oauth_code input').focus();
1
  function yst_popupwindow(url, w, h) {
2
+ 'use strict';
3
  var left = (screen.width/2)-(w/2);
4
  var top = (screen.height/8);
5
  return window.open(url, '', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width='+w+', height='+h+', top='+top+', left='+left);
6
  }
7
 
8
+ function yst_ga_switch_manual() {
9
+ if ( jQuery('#yoast-ga-form-checkbox-settings-manual_ua_code').is(':checked') ) {
10
+ var is_disabled = true;
11
+ jQuery('#enter_ua').show();
12
+ jQuery('#oauth_code').hide();
13
+ } else {
14
+ var is_disabled = false;
15
+ jQuery('#enter_ua').hide();
16
+ jQuery('#yoast-ga-form-text-settings-manual_ua_code_field').attr('value', '');
17
+ jQuery('#oauth_code').hide();
18
+ }
19
+
20
+ jQuery('#yoast-ga-form-select-settings-analytics_profile').prop('disabled', is_disabled).trigger('chosen:updated');
21
+ jQuery('#yst_ga_authenticate').attr('disabled', is_disabled);
22
+ }
23
+
24
  jQuery(document).ready(function() {
25
+ 'use strict';
26
  jQuery('#ga-tabs').find('a').click(function() {
27
  jQuery('#ga-tabs').find('a').removeClass('nav-tab-active');
28
  jQuery('.gatab').removeClass('active');
51
  jQuery('#' + activeTab).addClass('active');
52
  jQuery('#' + activeTab + '-tab').addClass('nav-tab-active');
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  // Manually enter a UA code
55
+ jQuery('#yoast-ga-form-checkbox-settings-manual_ua_code').click( yst_ga_switch_manual );
56
  yst_ga_switch_manual();
57
 
58
  jQuery('#oauth_code').hide();
59
+ jQuery('#yst_ga_authenticate').click( function() {
60
  jQuery('#oauth_code').show();
61
  Focusable.setFocus(jQuery('#oauth_code'), {hideOnESC:true});
62
  jQuery('#oauth_code input').focus();
assets/js/yoast_ga_admin.min.js CHANGED
@@ -1 +1 @@
1
- function yst_popupwindow(a,b,c){var d=screen.width/2-b/2,e=screen.height/8;return window.open(a,"","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width="+b+", height="+c+", top="+e+", left="+d)}jQuery(document).ready(function(){function a(){jQuery("#yoast-ga-form-checkbox-settings-manual_ua_code").is(":checked")?(jQuery("#enter_ua").show(),jQuery("#yoast-ga-form-select-settings-analytics_profile").prop("disabled",!0).trigger("chosen:updated"),jQuery("#yst_ga_authenticate").attr("disabled",!0),jQuery("#oauth_code").hide()):(jQuery("#enter_ua").hide(),jQuery("#yoast-ga-form-text-settings-manual_ua_code_field").attr("value",""),jQuery("#yoast-ga-form-select-settings-analytics_profile").prop("disabled",!1).trigger("chosen:updated"),jQuery("#yst_ga_authenticate").attr("disabled",!1),jQuery("#oauth_code").show())}jQuery("#ga-tabs").find("a").click(function(){jQuery("#ga-tabs").find("a").removeClass("nav-tab-active"),jQuery(".gatab").removeClass("active");var a=jQuery(this).attr("id").replace("-tab","");jQuery("#"+a).addClass("active"),jQuery(this).addClass("nav-tab-active"),jQuery("#return_tab").val(a)}),jQuery("a.activate-link").click(function(){jQuery("#extensions.wpseotab").removeClass("active"),jQuery("#extensions-tab").removeClass("nav-tab-active"),jQuery("#licenses.wpseotab").addClass("active"),jQuery("#licenses-tab").addClass("nav-tab-active")});var b=window.location.hash.replace("#top#","");(""===b||"#_=_"===b)&&(b=jQuery(".gatab").attr("id")),jQuery("#"+b).addClass("active"),jQuery("#"+b+"-tab").addClass("nav-tab-active"),jQuery("#yoast-ga-form-checkbox-settings-manual_ua_code").click(function(){a()}),a(),jQuery("#oauth_code").hide(),jQuery("#yst_ga_authenticate").click(function(){jQuery("#oauth_code").show(),Focusable.setFocus(jQuery("#oauth_code"),{hideOnESC:!0}),jQuery("#oauth_code input").focus()}),jQuery(".nav-tab-active").click(),jQuery(".yoast_help").qtip({position:{corner:{target:"topMiddle",tooltip:"bottomLeft"}},show:{when:{event:"mouseover"}},hide:{fixed:!0,when:{event:"mouseout"}},style:{tip:"bottomLeft",name:"blue"}})});
1
+ function yst_popupwindow(a,b,c){"use strict";var d=screen.width/2-b/2,e=screen.height/8;return window.open(a,"","toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width="+b+", height="+c+", top="+e+", left="+d)}function yst_ga_switch_manual(){if(jQuery("#yoast-ga-form-checkbox-settings-manual_ua_code").is(":checked")){var a=!0;jQuery("#enter_ua").show(),jQuery("#oauth_code").hide()}else{var a=!1;jQuery("#enter_ua").hide(),jQuery("#yoast-ga-form-text-settings-manual_ua_code_field").attr("value",""),jQuery("#oauth_code").hide()}jQuery("#yoast-ga-form-select-settings-analytics_profile").prop("disabled",a).trigger("chosen:updated"),jQuery("#yst_ga_authenticate").attr("disabled",a)}jQuery(document).ready(function(){"use strict";jQuery("#ga-tabs").find("a").click(function(){jQuery("#ga-tabs").find("a").removeClass("nav-tab-active"),jQuery(".gatab").removeClass("active");var a=jQuery(this).attr("id").replace("-tab","");jQuery("#"+a).addClass("active"),jQuery(this).addClass("nav-tab-active"),jQuery("#return_tab").val(a)}),jQuery("a.activate-link").click(function(){jQuery("#extensions.wpseotab").removeClass("active"),jQuery("#extensions-tab").removeClass("nav-tab-active"),jQuery("#licenses.wpseotab").addClass("active"),jQuery("#licenses-tab").addClass("nav-tab-active")});var a=window.location.hash.replace("#top#","");(""===a||"#_=_"===a)&&(a=jQuery(".gatab").attr("id")),jQuery("#"+a).addClass("active"),jQuery("#"+a+"-tab").addClass("nav-tab-active"),jQuery("#yoast-ga-form-checkbox-settings-manual_ua_code").click(yst_ga_switch_manual),yst_ga_switch_manual(),jQuery("#oauth_code").hide(),jQuery("#yst_ga_authenticate").click(function(){jQuery("#oauth_code").show(),Focusable.setFocus(jQuery("#oauth_code"),{hideOnESC:!0}),jQuery("#oauth_code input").focus()}),jQuery(".nav-tab-active").click(),jQuery(".yoast_help").qtip({position:{corner:{target:"topMiddle",tooltip:"bottomLeft"}},show:{when:{event:"mouseover"}},hide:{fixed:!0,when:{event:"mouseout"}},style:{tip:"bottomLeft",name:"blue"}})});
frontend/abstract-class-tracking.php CHANGED
@@ -1,365 +1,415 @@
1
  <?php
 
2
  /**
3
  * The basic frontend tracking class for the GA plugin, extendable for the children
4
  */
5
-
6
- abstract class Yoast_GA_Tracking {
7
-
8
- /**
9
- * Regular expression for Ga.js and universal tracking to detect links
10
- * @var string
11
- */
12
- protected $link_regex = '/<a\s+([^>]*?)href=[\'\"](.*?):(\/\/)?([^\'\"]+?)[\'\"]\s?(.*?)>(.*?)<\/a>/i';
13
-
14
- /**
15
- * Storage for the currently set options
16
- * @var mixed|void
17
- */
18
- protected $options;
19
-
20
- /**
21
- * Should the tracking code be added
22
- * @var bool
23
- */
24
- protected $do_tracking;
25
-
26
- /**
27
- * Function to output the GA Tracking code in the wp_head()
28
- *
29
- * @param bool $return_array
30
- *
31
- * @return mixed
32
- */
33
- abstract public function tracking( $return_array = false );
34
-
35
- /**
36
- * Output tracking link
37
- *
38
- * @param $label
39
- * @param $matches
40
- *
41
- * @return mixed
42
- */
43
- abstract protected function output_parse_link( $label, $matches );
44
-
45
- /**
46
- * Class constructor
47
- */
48
- public function __construct() {
49
-
50
- $this->options = Yoast_GA_Options::instance()->options;
51
- $this->do_tracking = $this->do_tracking();
52
-
53
- add_action( 'wp_head', array( $this, 'tracking' ), 8 );
54
-
55
- if ( $this->options['track_outbound'] == 1 ) {
56
- $this->track_outbound_filters();
57
- }
58
  }
 
59
 
60
- /**
61
- * Delegates `get_tracking_code` to the options class
62
- *
63
- * @return null
64
- */
65
- public function get_tracking_code() {
66
- return Yoast_GA_Options::instance()->get_tracking_code();
67
- }
68
 
69
- /**
70
- * Parse article link
71
- *
72
- * @param $matches
73
- *
74
- * @return mixed
75
- */
76
- public function parse_article_link( $matches ) {
77
- return $this->output_parse_link( 'outbound-article', $matches );
78
- }
79
 
80
- /**
81
- * Parse comment link
82
- *
83
- * @param $matches
84
- *
85
- * @return mixed
86
- */
87
- public function parse_comment_link( $matches ) {
88
- return $this->output_parse_link( 'outbound-comment', $matches );
89
- }
90
 
91
- /**
92
- * Parse widget link
93
- *
94
- * @param $matches
95
- *
96
- * @return mixed
97
- */
98
- public function parse_widget_link( $matches ) {
99
- return $this->output_parse_link( 'outbound-widget', $matches );
100
- }
101
 
102
- /**
103
- * Parse menu link
104
- *
105
- * @param $matches
106
- *
107
- * @return mixed
108
- */
109
- public function parse_nav_menu( $matches ) {
110
- return $this->output_parse_link( 'outbound-menu', $matches );
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
112
 
113
- /**
114
- * Parse the_content or the_excerpt for links
115
- *
116
- * @param $text
117
- *
118
- * @return mixed
119
- */
120
- public function the_content( $text ) {
121
- if ( false === $this->do_tracking ) {
122
- return $text;
123
- }
124
 
125
- if ( ! is_feed() ) {
126
- $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_article_link' ), $text );
127
- }
128
 
 
 
 
 
 
 
 
 
 
129
  return $text;
130
  }
 
131
 
132
- /**
133
- * Parse the widget content for links
134
- *
135
- * @param $text
136
- *
137
- * @return mixed
138
- */
139
- public function widget_content( $text ) {
140
- if ( ! $this->do_tracking ) {
141
- return $text;
142
- }
143
- $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_widget_link' ), $text );
144
 
 
 
 
 
 
 
 
 
 
145
  return $text;
146
  }
147
 
148
- /**
149
- * Parse the nav menu for links
150
- *
151
- * @param $text
152
- *
153
- * @return mixed
154
- */
155
- public function nav_menu( $text ) {
156
- if ( ! $this->do_tracking ) {
157
- return $text;
158
- }
159
 
160
- if ( ! is_feed() ) {
161
- $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_nav_menu' ), $text );
162
- }
163
 
 
 
 
 
 
 
 
 
 
164
  return $text;
165
  }
166
 
167
- /**
168
- * Parse comment text for links
169
- *
170
- * @param $text
171
- *
172
- * @return mixed
173
- */
174
- public function comment_text( $text ) {
175
- if ( ! $this->do_tracking ) {
176
- return $text;
177
- }
178
-
179
- if ( ! is_feed() ) {
180
- $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_comment_link' ), $text );
181
- }
182
-
183
- return $text;
184
  }
185
 
186
- /**
187
- * Parse the domain
188
- *
189
- * @param $uri
190
- *
191
- * @return array|bool
192
- */
193
- public function yoast_ga_get_domain( $uri ) {
194
- $hostPattern = '/^(https?:\/\/)?([^\/]+)/i';
195
- $domainPatternUS = '/[^\.\/]+\.[^\.\/]+$/';
196
- $domainPatternUK = '/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/';
197
-
198
- $matching = preg_match( $hostPattern, $uri, $matches );
199
- if ( $matching ) {
200
- $host = $matches[2];
201
- if ( preg_match( '/.*\..*\..*\..*$/', $host ) ) {
202
- preg_match( $domainPatternUK, $host, $matches );
203
- } else {
204
- preg_match( $domainPatternUS, $host, $matches );
205
- }
206
 
207
- if ( isset( $matches[0] ) ) {
208
- return array( 'domain' => $matches[0], 'host' => $host );
209
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
- return false;
212
  }
213
 
214
- /**
215
- * Merge the existing onclick with a new one and append it
216
- *
217
- * @param string $link_attribute
218
- * @param string $onclick
219
- *
220
- * @return string
221
- */
222
- public function output_add_onclick( $link_attribute, $onclick ) {
223
- if ( preg_match( '/onclick=[\'\"](.*?;)[\'\"]/i', $link_attribute, $matches ) > 0 ) {
224
- $js_snippet_single = 'onclick=\'' . $matches[1] . ' ' . $onclick . '\'';
225
- $js_snippet_double = 'onclick="' . $matches[1] . ' ' . $onclick . '"';
226
-
227
- $link_attribute = str_replace( 'onclick="' . $matches[1] . '"', $js_snippet_double, $link_attribute );
228
- $link_attribute = str_replace( "onclick='" . $matches[1] . "'", $js_snippet_single, $link_attribute );
229
 
230
- return $link_attribute;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  } else {
232
- if ( ! is_null( $onclick ) ) {
233
- return 'onclick="' . $onclick . '" ' . $link_attribute;
234
- } else {
235
- return $link_attribute;
236
- }
237
  }
238
  }
 
239
 
240
- /**
241
- * Generate the full URL
242
- *
243
- * @param string $link
244
- *
245
- * @return string
246
- */
247
- public function make_full_url( $link ) {
248
- switch ( $link['type'] ) {
249
- case 'download':
250
- case 'internal':
251
- case 'internal-as-outbound':
252
- case 'outbound':
253
- return $link['protocol'] . '://' . $link['original_url'];
254
- break;
255
- case 'email':
256
- return 'mailto:' . $link['original_url'];
257
- break;
258
- }
259
  }
 
260
 
261
- /**
262
- * Setting the filters for tracking outbound links
263
- *
264
- */
265
- protected function track_outbound_filters() {
266
- add_filter( 'the_content', array( $this, 'the_content' ), 99 );
267
- add_filter( 'widget_text', array( $this, 'widget_content' ), 99 );
268
- add_filter( 'wp_list_bookmarks', array( $this, 'widget_content' ), 99 );
269
- add_filter( 'wp_nav_menu', array( $this, 'widget_content' ), 99 );
270
- add_filter( 'the_excerpt', array( $this, 'the_content' ), 99 );
271
- add_filter( 'comment_text', array( $this, 'comment_text' ), 99 );
272
- }
273
 
274
- /**
275
- * Check if we need to show an actual tracking code
276
- *
277
- * @return bool
278
- */
279
- public function do_tracking() {
 
280
  global $current_user;
281
 
282
- if ( ! function_exists( 'get_currentuserinfo' ) ) {
283
- require_once( ABSPATH . 'wp-includes/pluggable.php' );
284
- }
285
-
286
  get_currentuserinfo();
287
 
288
- if ( 0 == $current_user->ID ) {
289
- return true;
290
- }
291
 
292
- if ( isset( $this->options['ignore_users'] ) ) {
293
  if ( ! empty( $current_user->roles ) && in_array( $current_user->roles[0], $this->options['ignore_users'] ) ) {
294
- return false;
295
  }
296
  }
297
- return true;
298
  }
299
 
300
- /**
301
- * Return the target with a lot of parameters
302
- *
303
- * @param string $category
304
- * @param array $matches
305
- *
306
- * @return array
307
- */
308
- protected function get_target( $category, $matches ) {
309
- $protocol = $matches[2];
310
- $original_url = $matches[4];
311
- $domain = $this->yoast_ga_get_domain( $matches[4] );
312
- $origin = $this->yoast_ga_get_domain( $_SERVER['HTTP_HOST'] );
313
- $download_extensions = explode( ',', str_replace( '.', '', $this->options['extensions_of_files'] ) );
314
- $extension = substr( strrchr( $original_url, '.' ), 1 );
315
-
316
- // Break out immediately if the link is not an http or https link.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
317
  $type = null;
318
- if ( $protocol !== 'http' && $protocol !== 'https' && $protocol !== 'mailto' ) {
319
- $type = null;
 
 
 
320
  } else {
321
- if ( ( $protocol == 'mailto' ) ) {
322
- $type = 'email';
323
- } elseif ( in_array( $extension, $download_extensions ) ) {
324
- $type = 'download';
325
- } else {
326
- if ( $domain['domain'] == $origin['domain'] ) {
327
- $out_links = explode( ',', $this->options['track_internal_as_outbound'] );
328
-
329
- if ( count( $out_links ) >= 1 ) {
330
- foreach ( $out_links as $out ) {
331
- if ( ! empty( $original_url ) && ! empty( $domain['domain'] ) ) {
332
- if ( strpos( $original_url, $domain['domain'] . $out ) !== false ) {
333
- $type = 'internal-as-outbound';
334
- }
335
- }
336
- }
337
- }
338
-
339
- if ( ! isset( $type ) ) {
340
- $type = 'internal';
341
- }
342
- } elseif ( $domain['domain'] != $origin['domain'] ) {
343
- $type = 'outbound';
 
 
 
 
344
  }
345
  }
346
  }
347
 
348
- return array(
349
- 'category' => $category,
350
- 'type' => $type,
351
- 'protocol' => $protocol,
352
- 'domain' => $domain['domain'],
353
- 'host' => $domain['host'],
354
- 'origin_domain' => $origin['domain'],
355
- 'origin_host' => $origin['host'],
356
- 'extension' => $extension,
357
- 'link_attributes' => rtrim( $matches[1] . ' ' . $matches[5] ),
358
- 'link_text' => $matches[6],
359
- 'original_url' => $original_url,
360
- );
361
  }
362
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
363
 
 
364
  }
365
 
 
1
  <?php
2
+
3
  /**
4
  * The basic frontend tracking class for the GA plugin, extendable for the children
5
  */
6
+ abstract class Yoast_GA_Tracking {
7
+
8
+ /**
9
+ * Regular expression for Ga.js and universal tracking to detect links
10
+ * @var string
11
+ */
12
+ protected $link_regex = '/<a\s+([^>]*?)href=[\'\"](.*?):(\/\/)?([^\'\"]+?)[\'\"]\s?(.*?)>(.*?)<\/a>/i';
13
+
14
+ /**
15
+ * Storage for the currently set options
16
+ * @var mixed|void
17
+ */
18
+ protected $options;
19
+
20
+ /**
21
+ * Should the tracking code be added
22
+ * @var bool
23
+ */
24
+ protected $do_tracking = null;
25
+
26
+ /**
27
+ * Function to output the GA Tracking code in the wp_head()
28
+ *
29
+ * @param bool $return_array
30
+ *
31
+ * @return mixed
32
+ */
33
+ abstract public function tracking( $return_array = false );
34
+
35
+ /**
36
+ * Output tracking link
37
+ *
38
+ * @param $label
39
+ * @param $matches
40
+ *
41
+ * @return mixed
42
+ */
43
+ abstract protected function output_parse_link( $label, $matches );
44
+
45
+ /**
46
+ * Class constructor
47
+ */
48
+ public function __construct() {
49
+
50
+ $this->options = Yoast_GA_Options::instance()->options;
51
+
52
+ add_action( 'wp_head', array( $this, 'tracking' ), 8 );
53
+
54
+ if ( $this->options['track_outbound'] == 1 ) {
55
+ $this->track_outbound_filters();
 
 
 
56
  }
57
+ }
58
 
59
+ /**
60
+ * Delegates `get_tracking_code` to the options class
61
+ *
62
+ * @return null
63
+ */
64
+ public function get_tracking_code() {
65
+ return Yoast_GA_Options::instance()->get_tracking_code();
66
+ }
67
 
68
+ /**
69
+ * Parse article link
70
+ *
71
+ * @param $matches
72
+ *
73
+ * @return mixed
74
+ */
75
+ public function parse_article_link( $matches ) {
76
+ return $this->output_parse_link( 'outbound-article', $matches );
77
+ }
78
 
79
+ /**
80
+ * Parse comment link
81
+ *
82
+ * @param $matches
83
+ *
84
+ * @return mixed
85
+ */
86
+ public function parse_comment_link( $matches ) {
87
+ return $this->output_parse_link( 'outbound-comment', $matches );
88
+ }
89
 
90
+ /**
91
+ * Parse widget link
92
+ *
93
+ * @param $matches
94
+ *
95
+ * @return mixed
96
+ */
97
+ public function parse_widget_link( $matches ) {
98
+ return $this->output_parse_link( 'outbound-widget', $matches );
99
+ }
100
 
101
+ /**
102
+ * Parse menu link
103
+ *
104
+ * @param $matches
105
+ *
106
+ * @return mixed
107
+ */
108
+ public function parse_nav_menu( $matches ) {
109
+ return $this->output_parse_link( 'outbound-menu', $matches );
110
+ }
111
+
112
+ /**
113
+ * Parse the_content or the_excerpt for links
114
+ *
115
+ * @param $text
116
+ *
117
+ * @return mixed
118
+ */
119
+ public function the_content( $text ) {
120
+ if ( false === $this->do_tracking() ) {
121
+ return $text;
122
  }
123
 
124
+ if ( ! is_feed() ) {
125
+ $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_article_link' ), $text );
126
+ }
 
 
 
 
 
 
 
 
127
 
128
+ return $text;
129
+ }
 
130
 
131
+ /**
132
+ * Parse the widget content for links
133
+ *
134
+ * @param $text
135
+ *
136
+ * @return mixed
137
+ */
138
+ public function widget_content( $text ) {
139
+ if ( ! $this->do_tracking() ) {
140
  return $text;
141
  }
142
+ $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_widget_link' ), $text );
143
 
144
+ return $text;
145
+ }
 
 
 
 
 
 
 
 
 
 
146
 
147
+ /**
148
+ * Parse the nav menu for links
149
+ *
150
+ * @param $text
151
+ *
152
+ * @return mixed
153
+ */
154
+ public function nav_menu( $text ) {
155
+ if ( ! $this->do_tracking() ) {
156
  return $text;
157
  }
158
 
159
+ if ( ! is_feed() ) {
160
+ $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_nav_menu' ), $text );
161
+ }
 
 
 
 
 
 
 
 
162
 
163
+ return $text;
164
+ }
 
165
 
166
+ /**
167
+ * Parse comment text for links
168
+ *
169
+ * @param $text
170
+ *
171
+ * @return mixed
172
+ */
173
+ public function comment_text( $text ) {
174
+ if ( ! $this->do_tracking() ) {
175
  return $text;
176
  }
177
 
178
+ if ( ! is_feed() ) {
179
+ $text = preg_replace_callback( $this->link_regex, array( $this, 'parse_comment_link' ), $text );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  }
181
 
182
+ return $text;
183
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
+ /**
186
+ * Parse the domain
187
+ *
188
+ * @param $uri
189
+ *
190
+ * @return array|bool
191
+ */
192
+ public function yoast_ga_get_domain( $uri ) {
193
+ $hostPattern = '/^(https?:\/\/)?([^\/]+)/i';
194
+ $domainPatternUS = '/[^\.\/]+\.[^\.\/]+$/';
195
+ $domainPatternUK = '/[^\.\/]+\.[^\.\/]+\.[^\.\/]+$/';
196
+
197
+ $matching = preg_match( $hostPattern, $uri, $matches );
198
+ if ( $matching ) {
199
+ $host = $matches[2];
200
+ if ( preg_match( '/.*\..*\..*\..*$/', $host ) ) {
201
+ preg_match( $domainPatternUK, $host, $matches );
202
+ } else {
203
+ preg_match( $domainPatternUS, $host, $matches );
204
+ }
205
+
206
+ if ( isset( $matches[0] ) ) {
207
+ return array( 'domain' => $matches[0], 'host' => $host );
208
  }
 
209
  }
210
 
211
+ return false;
212
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
213
 
214
+ /**
215
+ * Merge the existing onclick with a new one and append it
216
+ *
217
+ * @param string $link_attribute
218
+ * @param string $onclick
219
+ *
220
+ * @return string
221
+ */
222
+ public function output_add_onclick( $link_attribute, $onclick ) {
223
+ if ( preg_match( '/onclick=[\'\"](.*?;)[\'\"]/i', $link_attribute, $matches ) > 0 ) {
224
+ $js_snippet_single = 'onclick=\'' . $matches[1] . ' ' . $onclick . '\'';
225
+ $js_snippet_double = 'onclick="' . $matches[1] . ' ' . $onclick . '"';
226
+
227
+ $link_attribute = str_replace( 'onclick="' . $matches[1] . '"', $js_snippet_double, $link_attribute );
228
+ $link_attribute = str_replace( "onclick='" . $matches[1] . "'", $js_snippet_single, $link_attribute );
229
+
230
+ return $link_attribute;
231
+ } else {
232
+ if ( ! is_null( $onclick ) ) {
233
+ return 'onclick="' . $onclick . '" ' . $link_attribute;
234
  } else {
235
+ return $link_attribute;
 
 
 
 
236
  }
237
  }
238
+ }
239
 
240
+ /**
241
+ * Generate the full URL
242
+ *
243
+ * @param string $link
244
+ *
245
+ * @return string
246
+ */
247
+ public function make_full_url( $link ) {
248
+ switch ( $link['type'] ) {
249
+ case 'download':
250
+ case 'internal':
251
+ case 'internal-as-outbound':
252
+ case 'outbound':
253
+ return $link['protocol'] . '://' . $link['original_url'];
254
+ break;
255
+ case 'email':
256
+ return 'mailto:' . $link['original_url'];
257
+ break;
 
258
  }
259
+ }
260
 
261
+ /**
262
+ * Setting the filters for tracking outbound links
263
+ *
264
+ */
265
+ protected function track_outbound_filters() {
266
+ add_filter( 'the_content', array( $this, 'the_content' ), 99 );
267
+ add_filter( 'widget_text', array( $this, 'widget_content' ), 99 );
268
+ add_filter( 'wp_list_bookmarks', array( $this, 'widget_content' ), 99 );
269
+ add_filter( 'wp_nav_menu', array( $this, 'widget_content' ), 99 );
270
+ add_filter( 'the_excerpt', array( $this, 'the_content' ), 99 );
271
+ add_filter( 'comment_text', array( $this, 'comment_text' ), 99 );
272
+ }
273
 
274
+ /**
275
+ * Check if we need to show an actual tracking code
276
+ *
277
+ * @return bool
278
+ */
279
+ public function do_tracking() {
280
+ if ( $this->do_tracking === null ) {
281
  global $current_user;
282
 
 
 
 
 
283
  get_currentuserinfo();
284
 
285
+ $this->do_tracking = true;
 
 
286
 
287
+ if ( 0 != $current_user->ID && isset( $this->options['ignore_users'] ) ) {
288
  if ( ! empty( $current_user->roles ) && in_array( $current_user->roles[0], $this->options['ignore_users'] ) ) {
289
+ $this->do_tracking = false;
290
  }
291
  }
 
292
  }
293
 
294
+ return $this->do_tracking;
295
+ }
296
+
297
+ /**
298
+ * Return the target with a lot of parameters
299
+ *
300
+ * @param string $category
301
+ * @param array $matches
302
+ *
303
+ * @return array
304
+ */
305
+ protected function get_target( $category, $matches ) {
306
+ $protocol = $matches[2];
307
+ $original_url = $matches[4];
308
+ $domain = $this->yoast_ga_get_domain( $matches[4] );
309
+ $origin = $this->yoast_ga_get_domain( $_SERVER['HTTP_HOST'] );
310
+ $extension = substr( strrchr( $original_url, '.' ), 1 );
311
+ $type = $this->get_target_type( $extension, $domain, $origin, $matches );
312
+
313
+ return array(
314
+ 'category' => $category,
315
+ 'type' => $type,
316
+ 'protocol' => $protocol,
317
+ 'domain' => $domain['domain'],
318
+ 'host' => $domain['host'],
319
+ 'origin_domain' => $origin['domain'],
320
+ 'origin_host' => $origin['host'],
321
+ 'extension' => $extension,
322
+ 'link_attributes' => rtrim( $matches[1] . ' ' . $matches[5] ),
323
+ 'link_text' => $matches[6],
324
+ 'original_url' => $original_url,
325
+ );
326
+ }
327
+
328
+ /**
329
+ * Getting the type for current target
330
+ *
331
+ * @param string $extension
332
+ * @param array $domain
333
+ * @param array $origin
334
+ * @param array $matches
335
+ *
336
+ * @return null|string
337
+ */
338
+ protected function get_target_type( $extension, $domain, $origin, $matches ) {
339
+ $download_extensions = explode( ',', str_replace( '.', '', $this->options['extensions_of_files'] ) );
340
+ $download_extensions = array_map( 'trim', $download_extensions );
341
+ $protocol = $matches[2];
342
+ $original_url = $matches[4];
343
+
344
+ // Break out immediately if the link is not an http or https link.
345
+ $type = null;
346
+ if ( $protocol !== 'http' && $protocol !== 'https' && $protocol !== 'mailto' ) {
347
  $type = null;
348
+ } else {
349
+ if ( ( $protocol == 'mailto' ) ) {
350
+ $type = 'email';
351
+ } elseif ( in_array( $extension, $download_extensions ) ) {
352
+ $type = 'download';
353
  } else {
354
+ $type = $this->parse_outbound_type( $domain, $origin, $original_url );
355
+ }
356
+ }
357
+
358
+ return $type;
359
+ }
360
+
361
+ /**
362
+ * Parse the type for outbound links
363
+ *
364
+ * @param array $domain
365
+ * @param array $origin
366
+ * @param string $original_url
367
+ *
368
+ * @return string
369
+ */
370
+ protected function parse_outbound_type( $domain, $origin, $original_url ) {
371
+ $type = null;
372
+
373
+ if ( $domain['domain'] == $origin['domain'] ) {
374
+ $out_links = explode( ',', $this->options['track_internal_as_outbound'] );
375
+ $out_links = array_unique( array_map( 'trim', $out_links ) );
376
+
377
+ if ( ! empty( $original_url ) && ! empty( $domain['domain'] ) && count( $out_links ) >= 1 ) {
378
+ foreach ( $out_links as $out ) {
379
+ if ( ! empty( $out ) && strpos( $original_url, $domain['domain'] . $out ) !== false ) {
380
+ $type = 'internal-as-outbound';
381
  }
382
  }
383
  }
384
 
385
+ if ( ! isset( $type ) ) {
386
+ $type = 'internal';
387
+ }
388
+ } elseif ( $domain['domain'] != $origin['domain'] ) {
389
+ $type = 'outbound';
 
 
 
 
 
 
 
 
390
  }
391
 
392
+ return $type;
393
+ }
394
+
395
+ /**
396
+ * Trims the track_internal_as_label option to prevent commas and whitespaces
397
+ *
398
+ * @return string
399
+ */
400
+ protected function sanitize_internal_label() {
401
+ if ( ! is_null( $this->options['track_internal_as_label'] ) && ! empty( $this->options['track_internal_as_label'] ) ) {
402
+ $label = $this->options['track_internal_as_label'];
403
+ $label = trim( $label, ',' );
404
+ $label = trim( $label );
405
+ }
406
+
407
+ // Be sure label isn't empty, if so, set value with in
408
+ if ( empty( $label ) ) {
409
+ $label = 'int';
410
+ }
411
 
412
+ return $label;
413
  }
414
 
415
+ }
frontend/class-frontend.php CHANGED
@@ -1,59 +1,55 @@
1
  <?php
 
2
  /**
3
  * The basic frontend class for the GA plugin, extendable for the children
4
  */
 
5
 
6
- if ( ! class_exists( 'Yoast_GA_Frontend' ) ) {
7
 
8
- class Yoast_GA_Frontend {
 
 
 
9
 
10
- protected $options;
11
 
12
- /**
13
- * Class constructor
14
- */
15
- public function __construct() {
16
 
17
- $this->options = Yoast_GA_Options::instance()->options;
 
 
 
 
 
18
 
19
- if ( isset( $this->options['tag_links_in_rss'] ) && $this->options['tag_links_in_rss'] == 1 ) {
20
- add_filter( 'the_permalink_rss', array( $this, 'rsslinktagger' ), 99 );
21
- }
22
 
23
- // Check if the customer is running Universal or not (Enable in GA Settings -> Universal)
24
- if ( isset( $this->options['enable_universal'] ) && $this->options['enable_universal'] == 1 ) {
25
- new Yoast_GA_Universal;
 
 
 
 
 
 
 
 
 
26
  } else {
27
- new Yoast_GA_JS;
28
- }
29
-
30
- }
31
-
32
- /**
33
- * Add the UTM source parameters in the RSS feeds to track traffic
34
- *
35
- * @param string $guid
36
- *
37
- * @return string
38
- */
39
- public function rsslinktagger( $guid ) {
40
- global $post;
41
- if ( is_feed() ) {
42
- if ( $this->options['allow_anchor'] ) {
43
- $delimiter = '#';
44
- } else {
45
- $delimiter = '?';
46
- if ( strpos( $guid, $delimiter ) > 0 ) {
47
- $delimiter = '&amp;';
48
- }
49
  }
50
-
51
- return $guid . $delimiter . 'utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=' . urlencode( $post->post_name );
52
  }
53
 
54
- return $guid;
55
  }
56
 
 
57
  }
58
 
59
  }
1
  <?php
2
+
3
  /**
4
  * The basic frontend class for the GA plugin, extendable for the children
5
  */
6
+ class Yoast_GA_Frontend {
7
 
8
+ protected $options;
9
 
10
+ /**
11
+ * Class constructor
12
+ */
13
+ public function __construct() {
14
 
15
+ $this->options = Yoast_GA_Options::instance()->options;
16
 
17
+ if ( isset( $this->options['tag_links_in_rss'] ) && $this->options['tag_links_in_rss'] == 1 ) {
18
+ add_filter( 'the_permalink_rss', array( $this, 'rsslinktagger' ), 99 );
19
+ }
 
20
 
21
+ // Check if the customer is running Universal or not (Enable in GA Settings -> Universal)
22
+ if ( isset( $this->options['enable_universal'] ) && $this->options['enable_universal'] == 1 ) {
23
+ new Yoast_GA_Universal;
24
+ } else {
25
+ new Yoast_GA_JS;
26
+ }
27
 
28
+ }
 
 
29
 
30
+ /**
31
+ * Add the UTM source parameters in the RSS feeds to track traffic
32
+ *
33
+ * @param string $guid
34
+ *
35
+ * @return string
36
+ */
37
+ public function rsslinktagger( $guid ) {
38
+ global $post;
39
+ if ( is_feed() ) {
40
+ if ( $this->options['allow_anchor'] ) {
41
+ $delimiter = '#';
42
  } else {
43
+ $delimiter = '?';
44
+ if ( strpos( $guid, $delimiter ) > 0 ) {
45
+ $delimiter = '&amp;';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  }
 
 
47
  }
48
 
49
+ return $guid . $delimiter . 'utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=' . urlencode( $post->post_name );
50
  }
51
 
52
+ return $guid;
53
  }
54
 
55
  }
frontend/class-ga-js.php CHANGED
@@ -1,188 +1,182 @@
1
  <?php
 
2
  /**
3
  * The frontend JS class
4
  */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
- if ( ! class_exists( 'Yoast_GA_JS' ) ) {
7
-
8
- class Yoast_GA_JS extends Yoast_GA_Tracking {
9
-
10
- /**
11
- * Function to output the GA Tracking code in the wp_head()
12
- *
13
- * @param bool $return_array
14
- * @return array
15
- */
16
- public function tracking( $return_array = false ) {
17
- global $wp_query;
18
-
19
- if ( $this->do_tracking && ! is_preview() ) {
20
- $gaq_push = array();
21
-
22
- // Running action for adding possible code
23
- do_action( 'yst_tracking' );
24
-
25
- if ( isset( $this->options['subdomain_tracking'] ) && $this->options['subdomain_tracking'] != '' ) {
26
- $domain = $this->options['subdomain_tracking'];
27
- } else {
28
- $domain = null; // Default domain value
29
- }
30
-
31
- if ( ! isset( $this->options['allowanchor'] ) ) {
32
- $this->options['allowanchor'] = false;
33
- }
34
 
35
- $ua_code = $this->get_tracking_code();
36
- if ( is_null( $ua_code ) && $return_array == false ) {
37
- return;
38
- }
39
 
40
- $gaq_push[] = "'_setAccount', '" . $ua_code . "'";
41
 
42
- if ( ! is_null( $domain ) ) {
43
- $gaq_push[] = "'_setDomainName', '" . $domain . "'";
44
- }
45
 
46
- if ( isset( $this->options['allowanchor'] ) && $this->options['allowanchor'] ) {
47
- $gaq_push[] = "'_setAllowAnchor', true";
48
- }
49
 
50
- if ( $this->options['add_allow_linker'] ) {
51
- $gaq_push[] = "'_setAllowLinker', true";
52
- }
53
 
54
- // @todo, check for AllowLinker in GA.js? Universal only?
55
 
56
- // SSL data
57
- $gaq_push[] = "'_gat._forceSSL'";
58
 
59
- if ( ! empty( $this->options['custom_code'] ) ) {
60
- // Add custom code to the view
61
- $gaq_push[] = array(
62
- 'type' => 'custom_code',
63
- 'value' => stripslashes( $this->options['custom_code'] ),
64
- );
65
- }
66
 
67
- // Anonymous data
68
- if ( $this->options['anonymize_ips'] == 1 ) {
69
- $gaq_push[] = "'_gat._anonymizeIp'";
70
- }
71
 
72
- if ( isset( $this->options['allowhash'] ) && $this->options['allowhash'] ) {
73
- $gaq_push[] = "'_gat._anonymizeIp',true";
74
- }
75
 
76
- if ( is_404() ) {
77
- $gaq_push[] = "'_trackPageview','/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
78
- } else {
79
- if ( $wp_query->is_search ) {
80
- $pushstr = "'_trackPageview','/?s=";
81
- if ( $wp_query->found_posts == 0 ) {
82
- $gaq_push[] = $pushstr . 'no-results:' . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=no-results'";
 
 
 
83
  } else {
84
- if ( $wp_query->found_posts == 1 ) {
85
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=1-result'";
86
  } else {
87
- if ( $wp_query->found_posts > 1 && $wp_query->found_posts < 6 ) {
88
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=2-5-results'";
89
- } else {
90
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=plus-5-results'";
91
- }
92
  }
93
  }
94
- } else {
95
- $gaq_push[] = "'_trackPageview'";
96
  }
 
 
97
  }
 
98
 
99
- /**
100
- * Filter: 'yoast-ga-push-array-ga-js' - Allows filtering of the commands to push
101
- *
102
- * @api array $gaq_push
103
- */
104
- if ( true == $return_array ) {
105
- return $gaq_push;
106
- }
107
 
108
- $gaq_push = apply_filters( 'yoast-ga-push-array-ga-js', $gaq_push );
109
 
110
- $ga_settings = $this->options; // Assign the settings to the javascript include view
111
 
112
 
113
- // Include the tracking view
114
- if ( $this->options['debug_mode'] == 1 ) {
115
- require( 'views/tracking-debug.php' );
116
- } else {
117
- require( 'views/tracking-ga-js.php' );
118
- }
119
  } else {
120
- require( 'views/tracking-usergroup.php' );
121
  }
 
 
122
  }
 
123
 
124
- /**
125
- * Get tracking prefix
126
- *
127
- * @return string
128
- */
129
- public function get_tracking_prefix() {
130
- return ( empty( $this->options['trackprefix'] ) ) ? '/yoast-ga/' : $this->options['trackprefix'];
131
- }
132
-
133
- /**
134
- * Ouput tracking link
135
- *
136
- * @param string $label
137
- * @param array $matches
138
- *
139
- * @return mixed
140
- */
141
- protected function output_parse_link( $label, $matches ) {
142
- $link = $this->get_target( $label, $matches );
143
-
144
- // bail early for links that we can't handle
145
- if ( is_null( $link['type'] ) || 'internal' === $link['type'] ) {
146
- return $matches[0];
147
- }
148
-
149
- $onclick = null;
150
- $full_url = $this->make_full_url( $link );
151
 
152
- switch ( $link['type'] ) {
153
- case 'download':
154
- if ( $this->options['track_download_as'] == 'pageview' ) {
155
- $onclick = "_gaq.push(['_trackPageview','download/" . esc_attr( $full_url ) . "']);";
156
- } else {
157
- $onclick = "_gaq.push(['_trackEvent','download','" . esc_attr( $full_url ) . "']);";
158
- }
 
 
 
 
 
 
 
 
159
 
160
- break;
161
- case 'email':
162
- $onclick = "_gaq.push(['_trackEvent','mailto','" . esc_attr( $link['original_url'] ) . "']);";
163
 
164
- break;
165
- case 'internal-as-outbound':
166
- if ( ! is_null( $this->options['track_internal_as_label'] ) && ! empty( $this->options['track_internal_as_label'] ) ) {
167
- $label = $this->options['track_internal_as_label'];
168
- } else {
169
- $label = 'int';
170
- }
171
 
172
- $onclick = "_gaq.push(['_trackEvent', '" . esc_attr( $link['category'] ) . '-' . esc_attr( $label ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "']);";
 
 
173
 
174
- break;
175
- case 'outbound':
176
- $onclick = "_gaq.push(['_trackEvent', '" . esc_attr( $link['category'] ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "']);";
177
 
178
- break;
179
- }
180
 
181
- $link['link_attributes'] = $this->output_add_onclick( $link['link_attributes'], $onclick );
 
 
182
 
183
- return '<a href="' . $full_url . '" ' . $link['link_attributes'] . '>' . $link['link_text'] . '</a>';
184
  }
185
 
 
 
 
186
  }
187
 
188
  }
 
1
  <?php
2
+
3
  /**
4
  * The frontend JS class
5
  */
6
+ class Yoast_GA_JS extends Yoast_GA_Tracking {
7
+
8
+ /**
9
+ * Function to output the GA Tracking code in the wp_head()
10
+ *
11
+ * @param bool $return_array
12
+ *
13
+ * @return array
14
+ */
15
+ public function tracking( $return_array = false ) {
16
+ global $wp_query;
17
+
18
+ if ( $this->do_tracking() && ! is_preview() ) {
19
+ $gaq_push = array();
20
+
21
+ // Running action for adding possible code
22
+ do_action( 'yst_tracking' );
23
+
24
+ if ( isset( $this->options['subdomain_tracking'] ) && $this->options['subdomain_tracking'] != '' ) {
25
+ $domain = $this->options['subdomain_tracking'];
26
+ } else {
27
+ $domain = null; // Default domain value
28
+ }
29
 
30
+ if ( ! isset( $this->options['allowanchor'] ) ) {
31
+ $this->options['allowanchor'] = false;
32
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
 
34
+ $ua_code = $this->get_tracking_code();
35
+ if ( is_null( $ua_code ) && $return_array == false ) {
36
+ return;
37
+ }
38
 
39
+ $gaq_push[] = "'_setAccount', '" . $ua_code . "'";
40
 
41
+ if ( ! is_null( $domain ) ) {
42
+ $gaq_push[] = "'_setDomainName', '" . $domain . "'";
43
+ }
44
 
45
+ if ( isset( $this->options['allowanchor'] ) && $this->options['allowanchor'] ) {
46
+ $gaq_push[] = "'_setAllowAnchor', true";
47
+ }
48
 
49
+ if ( $this->options['add_allow_linker'] ) {
50
+ $gaq_push[] = "'_setAllowLinker', true";
51
+ }
52
 
53
+ // @todo, check for AllowLinker in GA.js? Universal only?
54
 
55
+ // SSL data
56
+ $gaq_push[] = "'_gat._forceSSL'";
57
 
58
+ if ( ! empty( $this->options['custom_code'] ) ) {
59
+ // Add custom code to the view
60
+ $gaq_push[] = array(
61
+ 'type' => 'custom_code',
62
+ 'value' => stripslashes( $this->options['custom_code'] ),
63
+ );
64
+ }
65
 
66
+ // Anonymous data
67
+ if ( $this->options['anonymize_ips'] == 1 ) {
68
+ $gaq_push[] = "'_gat._anonymizeIp'";
69
+ }
70
 
71
+ if ( isset( $this->options['allowhash'] ) && $this->options['allowhash'] ) {
72
+ $gaq_push[] = "'_gat._anonymizeIp',true";
73
+ }
74
 
75
+ if ( is_404() ) {
76
+ $gaq_push[] = "'_trackPageview','/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
77
+ } else {
78
+ if ( $wp_query->is_search ) {
79
+ $pushstr = "'_trackPageview','/?s=";
80
+ if ( $wp_query->found_posts == 0 ) {
81
+ $gaq_push[] = $pushstr . 'no-results:' . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=no-results'";
82
+ } else {
83
+ if ( $wp_query->found_posts == 1 ) {
84
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=1-result'";
85
  } else {
86
+ if ( $wp_query->found_posts > 1 && $wp_query->found_posts < 6 ) {
87
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=2-5-results'";
88
  } else {
89
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=plus-5-results'";
 
 
 
 
90
  }
91
  }
 
 
92
  }
93
+ } else {
94
+ $gaq_push[] = "'_trackPageview'";
95
  }
96
+ }
97
 
98
+ /**
99
+ * Filter: 'yoast-ga-push-array-ga-js' - Allows filtering of the commands to push
100
+ *
101
+ * @api array $gaq_push
102
+ */
103
+ if ( true == $return_array ) {
104
+ return $gaq_push;
105
+ }
106
 
107
+ $gaq_push = apply_filters( 'yoast-ga-push-array-ga-js', $gaq_push );
108
 
109
+ $ga_settings = $this->options; // Assign the settings to the javascript include view
110
 
111
 
112
+ // Include the tracking view
113
+ if ( $this->options['debug_mode'] == 1 ) {
114
+ require( 'views/tracking-debug.php' );
 
 
 
115
  } else {
116
+ require( 'views/tracking-ga-js.php' );
117
  }
118
+ } else {
119
+ require( 'views/tracking-usergroup.php' );
120
  }
121
+ }
122
 
123
+ /**
124
+ * Get tracking prefix
125
+ *
126
+ * @return string
127
+ */
128
+ public function get_tracking_prefix() {
129
+ return ( empty( $this->options['trackprefix'] ) ) ? '/yoast-ga/' : $this->options['trackprefix'];
130
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
+ /**
133
+ * Ouput tracking link
134
+ *
135
+ * @param string $label
136
+ * @param array $matches
137
+ *
138
+ * @return mixed
139
+ */
140
+ protected function output_parse_link( $label, $matches ) {
141
+ $link = $this->get_target( $label, $matches );
142
+
143
+ // bail early for links that we can't handle
144
+ if ( is_null( $link['type'] ) || 'internal' === $link['type'] ) {
145
+ return $matches[0];
146
+ }
147
 
148
+ $onclick = null;
149
+ $full_url = $this->make_full_url( $link );
 
150
 
151
+ switch ( $link['type'] ) {
152
+ case 'download':
153
+ if ( $this->options['track_download_as'] == 'pageview' ) {
154
+ $onclick = "_gaq.push(['_trackPageview','download/" . esc_attr( $full_url ) . "']);";
155
+ } else {
156
+ $onclick = "_gaq.push(['_trackEvent','download','" . esc_attr( $full_url ) . "']);";
157
+ }
158
 
159
+ break;
160
+ case 'email':
161
+ $onclick = "_gaq.push(['_trackEvent','mailto','" . esc_attr( $link['original_url'] ) . "']);";
162
 
163
+ break;
164
+ case 'internal-as-outbound':
165
+ $label = $this->sanitize_internal_label();
166
 
167
+ $onclick = "_gaq.push(['_trackEvent', '" . esc_attr( $link['category'] ) . '-' . esc_attr( $label ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "']);";
 
168
 
169
+ break;
170
+ case 'outbound':
171
+ $onclick = "_gaq.push(['_trackEvent', '" . esc_attr( $link['category'] ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "']);";
172
 
173
+ break;
174
  }
175
 
176
+ $link['link_attributes'] = $this->output_add_onclick( $link['link_attributes'], $onclick );
177
+
178
+ return '<a href="' . $full_url . '" ' . $link['link_attributes'] . '>' . $link['link_text'] . '</a>';
179
  }
180
 
181
  }
182
+
frontend/class-universal.php CHANGED
@@ -1,182 +1,175 @@
1
  <?php
 
2
  /**
3
  * This is the frontend class for the GA Universal code
4
  */
 
5
 
6
- if ( ! class_exists( 'Yoast_GA_Universal' ) ) {
7
-
8
- class Yoast_GA_Universal extends Yoast_GA_Tracking {
 
 
9
 
10
- /**
11
- * Function to output the GA Tracking code in the wp_head()
12
- */
13
- public function tracking( $return_array = false ) {
14
- global $wp_query;
15
 
16
- if ( $this->do_tracking && ! is_preview() ) {
17
- $gaq_push = array();
18
 
19
- // Running action for adding possible code
20
- do_action( 'yst_tracking' );
21
-
22
- if ( isset( $this->options['subdomain_tracking'] ) && $this->options['subdomain_tracking'] != '' ) {
23
- $domain = $this->options['subdomain_tracking'];
24
- } else {
25
- $domain = 'auto'; // Default domain value
26
- }
27
 
28
- if ( ! isset( $this->options['allowanchor'] ) ) {
29
- $this->options['allowanchor'] = false;
30
- }
31
 
32
- $ua_code = $this->get_tracking_code();
33
- if ( is_null( $ua_code ) && $return_array == false ) {
34
- return;
35
- }
36
 
37
- // Set tracking code here
38
- if ( ! empty( $ua_code ) ) {
39
- if ( $this->options['add_allow_linker'] && ! $this->options['allow_anchor'] ) {
40
- $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowLinker': true}";
 
 
 
41
  } else {
42
- if ( $this->options['allow_anchor'] && ! $this->options['add_allow_linker'] ) {
43
- $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowAnchor': true}";
44
  } else {
45
- if ( $this->options['allow_anchor'] && $this->options['add_allow_linker'] ) {
46
- $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowAnchor': true, 'allowLinker': true}";
47
- } else {
48
- $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "'";
49
- }
50
  }
51
  }
52
  }
 
53
 
54
- $gaq_push[] = "'set', 'forceSSL', true";
55
 
56
- if ( ! empty( $this->options['custom_code'] ) ) {
57
- // Add custom code to the view
58
- $gaq_push[] = array(
59
- 'type' => 'custom_code',
60
- 'value' => stripslashes( $this->options['custom_code'] ),
61
- );
62
- }
63
 
64
- // Anonymous data
65
- if ( $this->options['anonymize_ips'] == 1 ) {
66
- $gaq_push[] = "'set', 'anonymizeIp', true";
67
- }
68
 
69
- // add demographics
70
- if ( $this->options['demographics'] ) {
71
- $gaq_push[] = "'require', 'displayfeatures'";
72
- }
73
 
74
- if ( isset( $this->options['allowhash'] ) && $this->options['allowhash'] ) {
75
- $gaq_push[] = "'_setAllowHash',false";
76
- }
77
 
78
- if ( is_404() ) {
79
- $gaq_push[] = "'send','pageview','/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
80
- } else {
81
- if ( $wp_query->is_search ) {
82
- $pushstr = "'send','pageview','/?s=";
83
- if ( $wp_query->found_posts == 0 ) {
84
- $gaq_push[] = $pushstr . 'no-results:' . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=no-results'";
 
 
 
85
  } else {
86
- if ( $wp_query->found_posts == 1 ) {
87
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=1-result'";
88
  } else {
89
- if ( $wp_query->found_posts > 1 && $wp_query->found_posts < 6 ) {
90
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=2-5-results'";
91
- } else {
92
- $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=plus-5-results'";
93
- }
94
  }
95
  }
96
- } else {
97
- $gaq_push[] = "'send','pageview'";
98
  }
 
 
99
  }
 
100
 
101
- /**
102
- * Filter: 'yoast-ga-push-array-universal' - Allows filtering of the commands to push
103
- *
104
- * @api array $gaq_push
105
- */
106
- if ( true == $return_array ) {
107
- return $gaq_push;
108
- }
109
 
110
- $gaq_push = apply_filters( 'yoast-ga-push-array-universal', $gaq_push );
111
 
112
- $ga_settings = $this->options; // Assign the settings to the javascript include view
113
 
114
- // Include the tracking view
115
- if ( $this->options['debug_mode'] == 1 ) {
116
- require( 'views/tracking-debug.php' );
117
- } else {
118
- require( 'views/tracking-universal.php' );
119
- }
120
  } else {
121
- require( 'views/tracking-usergroup.php' );
122
  }
 
 
123
  }
 
124
 
125
- /**
126
- * Ouput tracking link
127
- *
128
- * @param string $label
129
- * @param array $matches
130
- *
131
- * @return mixed
132
- */
133
- protected function output_parse_link( $label, $matches ) {
134
- $link = $this->get_target( $label, $matches );
135
-
136
- // bail early for links that we can't handle
137
- if ( is_null( $link['type'] ) || 'internal' === $link['type'] ) {
138
- return $matches[0];
139
- }
140
-
141
- $onclick = null;
142
- $full_url = $this->make_full_url( $link );
143
 
144
- switch ( $link['type'] ) {
145
- case 'download':
146
- if ( $this->options['track_download_as'] == 'pageview' ) {
147
- $onclick = "__gaTracker('send', 'pageview', '" . esc_attr( $full_url ) . "');";
148
- } else {
149
- $onclick = "__gaTracker('send', 'event', 'download', '" . esc_attr( $full_url ) . "');";
150
- }
151
 
152
- break;
153
- case 'email':
154
- $onclick = "__gaTracker('send', 'event', 'mailto', '" . esc_attr( $link['original_url'] ) . "');";
 
 
 
 
155
 
156
- break;
157
- case 'internal-as-outbound':
158
- if ( ! is_null( $this->options['track_internal_as_label'] ) && ! empty( $this->options['track_internal_as_label'] ) ) {
159
- $label = $this->options['track_internal_as_label'];
160
- } else {
161
- $label = 'int';
162
- }
163
 
164
- $onclick = "__gaTracker('send', 'event', '" . esc_attr( $link['category'] ) . '-' . esc_attr( $label ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "');";
 
 
165
 
166
- break;
167
- case 'outbound':
168
- if ( $this->options['track_outbound'] == 1 ) {
169
- $onclick = "__gaTracker('send', 'event', '" . esc_attr( $link['category'] ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "');";
170
- }
171
 
172
- break;
173
- }
 
 
 
174
 
175
- $link['link_attributes'] = $this->output_add_onclick( $link['link_attributes'], $onclick );
 
176
 
177
- return '<a href="' . $full_url . '" ' . $link['link_attributes'] . '>' . $link['link_text'] . '</a>';
178
 
179
- }
180
 
181
  }
182
- }
 
1
  <?php
2
+
3
  /**
4
  * This is the frontend class for the GA Universal code
5
  */
6
+ class Yoast_GA_Universal extends Yoast_GA_Tracking {
7
 
8
+ /**
9
+ * Function to output the GA Tracking code in the wp_head()
10
+ */
11
+ public function tracking( $return_array = false ) {
12
+ global $wp_query;
13
 
14
+ if ( $this->do_tracking() && ! is_preview() ) {
15
+ $gaq_push = array();
 
 
 
16
 
17
+ // Running action for adding possible code
18
+ do_action( 'yst_tracking' );
19
 
20
+ if ( isset( $this->options['subdomain_tracking'] ) && $this->options['subdomain_tracking'] != '' ) {
21
+ $domain = $this->options['subdomain_tracking'];
22
+ } else {
23
+ $domain = 'auto'; // Default domain value
24
+ }
 
 
 
25
 
26
+ if ( ! isset( $this->options['allowanchor'] ) ) {
27
+ $this->options['allowanchor'] = false;
28
+ }
29
 
30
+ $ua_code = $this->get_tracking_code();
31
+ if ( is_null( $ua_code ) && $return_array == false ) {
32
+ return;
33
+ }
34
 
35
+ // Set tracking code here
36
+ if ( ! empty( $ua_code ) ) {
37
+ if ( $this->options['add_allow_linker'] && ! $this->options['allow_anchor'] ) {
38
+ $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowLinker': true}";
39
+ } else {
40
+ if ( $this->options['allow_anchor'] && ! $this->options['add_allow_linker'] ) {
41
+ $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowAnchor': true}";
42
  } else {
43
+ if ( $this->options['allow_anchor'] && $this->options['add_allow_linker'] ) {
44
+ $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "', {'allowAnchor': true, 'allowLinker': true}";
45
  } else {
46
+ $gaq_push[] = "'create', '" . $ua_code . "', '" . $domain . "'";
 
 
 
 
47
  }
48
  }
49
  }
50
+ }
51
 
52
+ $gaq_push[] = "'set', 'forceSSL', true";
53
 
54
+ if ( ! empty( $this->options['custom_code'] ) ) {
55
+ // Add custom code to the view
56
+ $gaq_push[] = array(
57
+ 'type' => 'custom_code',
58
+ 'value' => stripslashes( $this->options['custom_code'] ),
59
+ );
60
+ }
61
 
62
+ // Anonymous data
63
+ if ( $this->options['anonymize_ips'] == 1 ) {
64
+ $gaq_push[] = "'set', 'anonymizeIp', true";
65
+ }
66
 
67
+ // add demographics
68
+ if ( $this->options['demographics'] ) {
69
+ $gaq_push[] = "'require', 'displayfeatures'";
70
+ }
71
 
72
+ if ( isset( $this->options['allowhash'] ) && $this->options['allowhash'] ) {
73
+ $gaq_push[] = "'_setAllowHash',false";
74
+ }
75
 
76
+ if ( is_404() ) {
77
+ $gaq_push[] = "'send','pageview','/404.html?page=' + document.location.pathname + document.location.search + '&from=' + document.referrer";
78
+ } else {
79
+ if ( $wp_query->is_search ) {
80
+ $pushstr = "'send','pageview','/?s=";
81
+ if ( $wp_query->found_posts == 0 ) {
82
+ $gaq_push[] = $pushstr . 'no-results:' . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=no-results'";
83
+ } else {
84
+ if ( $wp_query->found_posts == 1 ) {
85
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=1-result'";
86
  } else {
87
+ if ( $wp_query->found_posts > 1 && $wp_query->found_posts < 6 ) {
88
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=2-5-results'";
89
  } else {
90
+ $gaq_push[] = $pushstr . rawurlencode( $wp_query->query_vars['s'] ) . "&cat=plus-5-results'";
 
 
 
 
91
  }
92
  }
 
 
93
  }
94
+ } else {
95
+ $gaq_push[] = "'send','pageview'";
96
  }
97
+ }
98
 
99
+ /**
100
+ * Filter: 'yoast-ga-push-array-universal' - Allows filtering of the commands to push
101
+ *
102
+ * @api array $gaq_push
103
+ */
104
+ if ( true == $return_array ) {
105
+ return $gaq_push;
106
+ }
107
 
108
+ $gaq_push = apply_filters( 'yoast-ga-push-array-universal', $gaq_push );
109
 
110
+ $ga_settings = $this->options; // Assign the settings to the javascript include view
111
 
112
+ // Include the tracking view
113
+ if ( $this->options['debug_mode'] == 1 ) {
114
+ require( 'views/tracking-debug.php' );
 
 
 
115
  } else {
116
+ require( 'views/tracking-universal.php' );
117
  }
118
+ } else {
119
+ require( 'views/tracking-usergroup.php' );
120
  }
121
+ }
122
 
123
+ /**
124
+ * Ouput tracking link
125
+ *
126
+ * @param string $label
127
+ * @param array $matches
128
+ *
129
+ * @return mixed
130
+ */
131
+ protected function output_parse_link( $label, $matches ) {
132
+ $link = $this->get_target( $label, $matches );
133
+
134
+ // bail early for links that we can't handle
135
+ if ( is_null( $link['type'] ) || 'internal' === $link['type'] ) {
136
+ return $matches[0];
137
+ }
 
 
 
138
 
139
+ $onclick = null;
140
+ $full_url = $this->make_full_url( $link );
 
 
 
 
 
141
 
142
+ switch ( $link['type'] ) {
143
+ case 'download':
144
+ if ( $this->options['track_download_as'] == 'pageview' ) {
145
+ $onclick = "__gaTracker('send', 'pageview', '" . esc_attr( $full_url ) . "');";
146
+ } else {
147
+ $onclick = "__gaTracker('send', 'event', 'download', '" . esc_attr( $full_url ) . "');";
148
+ }
149
 
150
+ break;
151
+ case 'email':
152
+ $onclick = "__gaTracker('send', 'event', 'mailto', '" . esc_attr( $link['original_url'] ) . "');";
 
 
 
 
153
 
154
+ break;
155
+ case 'internal-as-outbound':
156
+ $label = $this->sanitize_internal_label();
157
 
158
+ $onclick = "__gaTracker('send', 'event', '" . esc_attr( $link['category'] ) . '-' . esc_attr( $label ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "');";
 
 
 
 
159
 
160
+ break;
161
+ case 'outbound':
162
+ if ( $this->options['track_outbound'] == 1 ) {
163
+ $onclick = "__gaTracker('send', 'event', '" . esc_attr( $link['category'] ) . "', '" . esc_attr( $full_url ) . "', '" . esc_attr( strip_tags( $link['link_text'] ) ) . "');";
164
+ }
165
 
166
+ break;
167
+ }
168
 
169
+ $link['link_attributes'] = $this->output_add_onclick( $link['link_attributes'], $onclick );
170
 
171
+ return '<a href="' . $full_url . '" ' . $link['link_attributes'] . '>' . $link['link_text'] . '</a>';
172
 
173
  }
174
+
175
+ }
frontend/views/tracking-debug.php CHANGED
@@ -1,3 +1,3 @@
1
- <!-- This site uses the Yoast Google Analytics plugin v<?php echo GAWP_VERSION; ?> - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <!-- @Webmaster, normally you will find the Google Analytics tracking code here, but you have enabled the Debug Mode. Change that in Analytics -> (Tab) Debug mode and disable Debug Mode to enable the tracking of your site. -->
3
- <!-- / Yoast Google Analytics -->
1
+ <!-- This site uses the Google Analytics by Yoast plugin v<?php echo GAWP_VERSION; ?> - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <!-- @Webmaster, normally you will find the Google Analytics tracking code here, but you have enabled the Debug Mode. Change that in Analytics -> (Tab) Debug mode and disable Debug Mode to enable the tracking of your site. -->
3
+ <!-- / Google Analytics by Yoast -->
frontend/views/tracking-ga-js.php CHANGED
@@ -1,4 +1,4 @@
1
- <!-- This site uses the Yoast Google Analytics plugin v<?php echo GAWP_VERSION; ?> - Universal disabled - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <script type="text/javascript">
3
 
4
  var _gaq = _gaq || [];
@@ -26,4 +26,4 @@ if ( count( $gaq_push ) >= 1 ) {
26
  })();
27
 
28
  </script>
29
- <!-- / Yoast Google Analytics -->
1
+ <!-- This site uses the Google Analytics by Yoast plugin v<?php echo GAWP_VERSION; ?> - Universal disabled - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <script type="text/javascript">
3
 
4
  var _gaq = _gaq || [];
26
  })();
27
 
28
  </script>
29
+ <!-- / Google Analytics by Yoast -->
frontend/views/tracking-universal.php CHANGED
@@ -1,4 +1,4 @@
1
- <!-- This site uses the Yoast Google Analytics plugin v<?php echo GAWP_VERSION; ?> - Universal enabled - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <script type="text/javascript">
3
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
4
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
@@ -20,4 +20,4 @@
20
  ?>
21
 
22
  </script>
23
- <!-- / Yoast Google Analytics -->
1
+ <!-- This site uses the Google Analytics by Yoast plugin v<?php echo GAWP_VERSION; ?> - Universal enabled - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <script type="text/javascript">
3
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
4
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
20
  ?>
21
 
22
  </script>
23
+ <!-- / Google Analytics by Yoast -->
frontend/views/tracking-usergroup.php CHANGED
@@ -1,3 +1,3 @@
1
- <!-- This site uses the Yoast Google Analytics plugin v<?php echo GAWP_VERSION; ?> - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <!-- @Webmaster, normally you will find the Google Analytics tracking code here, but you are in the disabled user groups. Change that in Analytics -> Settings (Ignore usergroups) -->
3
- <!-- / Yoast Google Analytics -->
1
+ <!-- This site uses the Google Analytics by Yoast plugin v<?php echo GAWP_VERSION; ?> - https://yoast.com/wordpress/plugins/google-analytics/ -->
2
  <!-- @Webmaster, normally you will find the Google Analytics tracking code here, but you are in the disabled user groups. Change that in Analytics -> Settings (Ignore usergroups) -->
3
+ <!-- / Google Analytics by Yoast -->
googleanalytics.php CHANGED
@@ -2,9 +2,9 @@
2
  /*
3
  Plugin Name: Google Analytics by Yoast
4
  Plugin URI: https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
5
- Description: This plugin makes it simple to add Google Analytics to your WordPress blog, adding lots of features, eg. error page, search result and automatic clickout and download tracking.
6
  Author: Team Yoast
7
- Version: 5.2.8
8
  Requires at least: 3.8
9
  Author URI: https://yoast.com/
10
  License: GPL v3
@@ -12,7 +12,7 @@ Text Domain: google-analytics-for-wordpress
12
  Domain Path: /languages
13
 
14
  Google Analytics for WordPress
15
- Copyright (C) 2008-2014, Joost de Valk - joost@yoast.com
16
 
17
  This program is free software: you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
30
 
31
  // This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
32
 
33
- define( 'GAWP_VERSION', '5.2.8' );
34
 
35
  define( 'GAWP_FILE', __FILE__ );
36
 
2
  /*
3
  Plugin Name: Google Analytics by Yoast
4
  Plugin URI: https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&utm_medium=plugin&utm_campaign=wpgaplugin&utm_content=v504
5
+ Description: This plugin makes it simple to add Google Analytics to your WordPress site, adding lots of features, e.g. error page, search result and automatic outgoing links and download tracking.
6
  Author: Team Yoast
7
+ Version: 5.3
8
  Requires at least: 3.8
9
  Author URI: https://yoast.com/
10
  License: GPL v3
12
  Domain Path: /languages
13
 
14
  Google Analytics for WordPress
15
+ Copyright (C) 2008-2015, Team Yoast, support@yoast.com
16
 
17
  This program is free software: you can redistribute it and/or modify
18
  it under the terms of the GNU General Public License as published by
30
 
31
  // This plugin was originally based on Rich Boakes' Analytics plugin: http://boakes.org/analytics, but has since been rewritten and refactored multiple times.
32
 
33
+ define( 'GAWP_VERSION', '5.3' );
34
 
35
  define( 'GAWP_FILE', __FILE__ );
36
 
includes/class-autoload.php CHANGED
@@ -14,6 +14,7 @@ if ( ! class_exists( 'Yoast_GA_Autoload' ) ) {
14
 
15
  self::$classes = array(
16
  'yoast_ga_options' => 'includes/class-options',
 
17
  'yoast_ga_utils' => 'includes/class-utils',
18
 
19
  // Frontend classes
@@ -26,6 +27,7 @@ if ( ! class_exists( 'Yoast_GA_Autoload' ) ) {
26
  'yoast_ga_admin' => 'admin/class-admin',
27
  'yoast_ga_admin_menu' => 'admin/class-admin-menu',
28
  'yoast_google_analytics' => 'admin/class-google-analytics',
 
29
  'yoast_ga_admin_assets' => 'admin/class-admin-assets',
30
  'yoast_ga_admin_form' => 'admin/class-admin-form',
31
 
@@ -58,7 +60,7 @@ if ( ! class_exists( 'Yoast_GA_Autoload' ) ) {
58
  }
59
 
60
  $class_name = strtolower( $class );
61
- if ( isset( self::$classes[$class_name] ) ) {
62
  require_once $include_path . '/' . self::$classes[$class_name] . '.php';
63
  }
64
  }
14
 
15
  self::$classes = array(
16
  'yoast_ga_options' => 'includes/class-options',
17
+ 'yoast_ga_settings' => 'includes/class-settings',
18
  'yoast_ga_utils' => 'includes/class-utils',
19
 
20
  // Frontend classes
27
  'yoast_ga_admin' => 'admin/class-admin',
28
  'yoast_ga_admin_menu' => 'admin/class-admin-menu',
29
  'yoast_google_analytics' => 'admin/class-google-analytics',
30
+ 'yoast_google_analytics_notice' => 'admin/class-google-analytics',
31
  'yoast_ga_admin_assets' => 'admin/class-admin-assets',
32
  'yoast_ga_admin_form' => 'admin/class-admin-form',
33
 
60
  }
61
 
62
  $class_name = strtolower( $class );
63
+ if ( ! class_exists( $class ) && isset( self::$classes[$class_name] ) ) {
64
  require_once $include_path . '/' . self::$classes[$class_name] . '.php';
65
  }
66
  }
includes/class-options.php CHANGED
@@ -1,269 +1,274 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Options' ) ) {
4
-
5
- class Yoast_GA_Options {
6
-
7
- public $options;
8
-
9
- /**
10
- * Holds the settings for the GA plugin and possible subplugins
11
- *
12
- * @var string
13
- */
14
- public $option_name = 'yst_ga';
15
-
16
- /**
17
- * Holds the prefix we use within the option to save settings
18
- *
19
- * @var string
20
- */
21
- public $option_prefix = 'ga_general';
22
-
23
- /**
24
- * Holds the path to the main plugin file
25
- *
26
- * @var string
27
- */
28
- public $plugin_path;
29
-
30
- /**
31
- * Holds the URL to the main plugin directory
32
- *
33
- * @var string
34
- */
35
- public $plugin_url;
36
-
37
- /**
38
- * Saving instance of it's own in this static var
39
- *
40
- * @var object
41
- */
42
- private static $instance;
43
-
44
- /**
45
- * Getting instance of this object. If instance doesn't exists it will be created.
46
- *
47
- * @return object|Yoast_GA_Options
48
- */
49
- public static function instance() {
50
-
51
- if ( is_null( self::$instance ) ) {
52
- self::$instance = new Yoast_GA_Options();
53
- }
54
-
55
- return self::$instance;
56
-
57
  }
58
 
59
- /**
60
- * Constructor for the options
61
- */
62
- public function __construct() {
63
- $this->options = $this->get_options();
64
- $this->options = $this->check_options( $this->options );
65
-
66
- $this->plugin_path = plugin_dir_path( GAWP_FILE );
67
- $this->plugin_url = trailingslashit( plugin_dir_url( GAWP_FILE ) );
68
 
69
- if ( false == $this->options ) {
70
- add_option( $this->option_name, $this->default_ga_values() );
71
- $this->options = $this->get_options();
72
- }
73
 
74
- if ( ! isset( $this->options['version'] ) || $this->options['version'] < GAWP_VERSION ) {
75
- $this->upgrade();
76
- }
 
 
 
77
 
78
- // If instance is null, create it. Prevent creating multiple instances of this class
79
- if ( is_null( self::$instance ) ) {
80
- self::$instance = $this;
81
- }
82
 
83
- add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
 
 
84
  }
85
 
86
- /**
87
- * Updates the GA option within the current option_prefix
88
- *
89
- * @param array $val
90
- *
91
- * @return bool
92
- */
93
- public function update_option( $val ) {
94
- $options = get_option( $this->option_name );
95
- $options[$this->option_prefix] = $val;
96
-
97
- return update_option( $this->option_name, $options );
98
  }
99
 
100
- /**
101
- * Return the Google Analytics options
102
- *
103
- * @return mixed|void
104
- */
105
- public function get_options() {
106
- $options = get_option( $this->option_name );
107
-
108
- return $options[$this->option_prefix];
109
  }
110
 
111
- /**
112
- * Check if all the options are set, to prevent a notice if debugging is enabled
113
- * When we have new changes, the settings are saved to the options class
114
- *
115
- * @param $options
116
- *
117
- * @return mixed
118
- */
119
- public function check_options( $options ) {
120
-
121
- $changes = 0;
122
- foreach ( $this->default_ga_values() as $key => $value ) {
123
- if ( ! isset( $options[$key] ) ) {
124
- $options[$key] = $value;
125
- $changes ++;
126
- }
127
- }
128
 
129
- if ( $changes >= 1 ) {
130
- $this->update_option( $options );
131
- }
 
 
 
 
 
 
 
 
 
 
132
 
133
- return $options;
134
- }
 
 
 
 
 
135
 
136
- /**
137
- * Get the Google Analytics tracking code for this website
138
- *
139
- * @return null
140
- */
141
- public function get_tracking_code() {
142
- $tracking_code = null;
143
- $this->options = $this->get_options();
144
 
145
- if ( ! empty( $this->options['analytics_profile'] ) && ! empty( $this->options['analytics_profile_code'] ) ) {
146
- $tracking_code = $this->options['analytics_profile_code'];
147
- }
148
- elseif ( ! empty( $this->options['analytics_profile'] ) && empty( $this->options['analytics_profile_code'] ) ) {
149
- // Analytics profile is still holding the UA code
150
- $tracking_code = $this->options['analytics_profile'];
 
 
 
 
 
 
 
 
 
151
  }
 
152
 
153
- if ( ! empty( $this->options['manual_ua_code_field'] ) && ! empty( $this->options['manual_ua_code'] ) ) {
154
- $tracking_code = $this->options['manual_ua_code_field'];
155
- }
 
 
 
156
 
157
- return $tracking_code;
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  }
159
 
160
- /**
161
- * Upgrade the settings when settings are changed.
162
- *
163
- * @since 5.0.1
164
- */
165
- private function upgrade() {
166
- if ( ! isset( $this->options['version'] ) && is_null( $this->get_tracking_code() ) ) {
167
- $old_options = get_option( 'Yoast_Google_Analytics' );
168
-
169
- if ( isset( $old_options ) && is_array( $old_options ) ) {
170
- if ( isset( $old_options['uastring'] ) && '' !== trim( $old_options['uastring'] ) ) {
171
- // Save UA as manual UA, instead of saving all the old GA crap
172
- $this->options['manual_ua_code'] = 1;
173
- $this->options['manual_ua_code_field'] = $old_options['uastring'];
174
- }
175
-
176
- // Other settings
177
- $this->options['allow_anchor'] = $old_options['allowanchor'];
178
- $this->options['add_allow_linker'] = $old_options['allowlinker'];
179
- $this->options['anonymous_data'] = $old_options['anonymizeip'];
180
- $this->options['track_outbound'] = $old_options['trackoutbound'];
181
- $this->options['track_internal_as_outbound'] = $old_options['internallink'];
182
- $this->options['track_internal_as_label'] = $old_options['internallinklabel'];
183
- $this->options['extensions_of_files'] = $old_options['dlextensions'];
184
 
185
- }
 
186
 
187
- delete_option( 'Yoast_Google_Analytics' );
188
- }
 
 
 
 
 
 
 
 
 
 
 
189
 
190
- // 5.0.0 to 5.0.1 fix of ignore users array
191
- if ( ! isset( $this->options['version'] ) || version_compare( $this->options['version'], '5.0.1', '<' ) ) {
192
- if ( isset( $this->options['ignore_users'] ) && ! is_array( $this->options['ignore_users'] ) ) {
193
- $this->options['ignore_users'] = (array) $this->options['ignore_users'];
194
- }
195
- }
196
 
197
- // 5.1.2+ Remove firebug_lite from options, if set
198
- if ( ! isset ( $this->options['version'] ) || version_compare( $this->options['version'], '5.1.2', '<' ) ) {
199
- if ( isset( $this->options['firebug_lite'] ) ) {
200
- unset( $this->options['firebug_lite'] );
 
 
 
 
 
 
 
 
 
201
  }
 
 
 
 
 
 
 
 
202
  }
203
-
204
- // Check is API option already exists - if not add it
205
- $yst_ga_api = get_option( 'yst_ga_api' );
206
- if ( $yst_ga_api === false ) {
207
- add_option( 'yst_ga_api', array(), '', 'no' );
 
208
  }
209
-
210
- // Fallback to make sure every default option has a value
211
- $defaults = $this->default_ga_values();
212
- foreach ( $defaults[$this->option_prefix] as $key => $value ) {
213
- if ( ! isset( $this->options[$key] ) ) {
214
- $this->options[$key] = $value;
215
- }
216
  }
217
-
218
- // Set to the current version now that we've done all needed upgrades
219
- $this->options['version'] = GAWP_VERSION;
220
-
221
- $this->update_option( $this->options );
222
  }
223
-
224
- /**
225
- * Set the default GA settings here
226
- * @return array
227
- */
228
- public function default_ga_values() {
229
-
230
- $options = array(
231
- $this->option_prefix => array(
232
- 'analytics_profile' => null,
233
- 'analytics_profile_code' => null,
234
- 'manual_ua_code' => 0,
235
- 'manual_ua_code_field' => null,
236
- 'track_internal_as_outbound' => null,
237
- 'track_internal_as_label' => null,
238
- 'track_outbound' => 0,
239
- 'anonymous_data' => 0,
240
- 'enable_universal' => 0,
241
- 'demographics' => 0,
242
- 'ignore_users' => array( 'editor' ),
243
- 'anonymize_ips' => 0,
244
- 'track_download_as' => 'event',
245
- 'extensions_of_files' => 'doc,exe,js,pdf,ppt,tgz,zip,xls',
246
- 'track_full_url' => 'domain',
247
- 'subdomain_tracking' => null,
248
- 'tag_links_in_rss' => 0,
249
- 'allow_anchor' => 0,
250
- 'add_allow_linker' => 0,
251
- 'custom_code' => null,
252
- 'debug_mode' => 0,
253
- )
254
- );
255
-
256
- $options = apply_filters( 'yst_ga_default-ga-values', $options, $this->option_prefix );
257
-
258
- return $options;
259
  }
260
-
261
- /**
262
- * Load plugin textdomain
263
- */
264
- public static function load_textdomain() {
265
- load_plugin_textdomain( 'google-analytics-for-wordpress', false, dirname( plugin_basename( GAWP_FILE ) ) . '/languages/' );
266
  }
 
 
 
 
 
 
 
 
 
 
 
267
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
269
- }
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ class Yoast_GA_Options {
4
+
5
+ public $options;
6
+
7
+ /**
8
+ * Holds the settings for the GA plugin and possible subplugins
9
+ *
10
+ * @var string
11
+ */
12
+ public $option_name = 'yst_ga';
13
+
14
+ /**
15
+ * Holds the prefix we use within the option to save settings
16
+ *
17
+ * @var string
18
+ */
19
+ public $option_prefix = 'ga_general';
20
+
21
+ /**
22
+ * Holds the path to the main plugin file
23
+ *
24
+ * @var string
25
+ */
26
+ public $plugin_path;
27
+
28
+ /**
29
+ * Holds the URL to the main plugin directory
30
+ *
31
+ * @var string
32
+ */
33
+ public $plugin_url;
34
+
35
+ /**
36
+ * Saving instance of it's own in this static var
37
+ *
38
+ * @var object
39
+ */
40
+ private static $instance;
41
+
42
+ /**
43
+ * Getting instance of this object. If instance doesn't exists it will be created.
44
+ *
45
+ * @return object|Yoast_GA_Options
46
+ */
47
+ public static function instance() {
48
+
49
+ if ( is_null( self::$instance ) ) {
50
+ self::$instance = new Yoast_GA_Options();
 
 
 
 
 
 
51
  }
52
 
53
+ return self::$instance;
 
 
 
 
 
 
 
 
54
 
55
+ }
 
 
 
56
 
57
+ /**
58
+ * Constructor for the options
59
+ */
60
+ public function __construct() {
61
+ $this->options = $this->get_options();
62
+ $this->options = $this->check_options( $this->options );
63
 
64
+ $this->plugin_path = plugin_dir_path( GAWP_FILE );
65
+ $this->plugin_url = trailingslashit( plugin_dir_url( GAWP_FILE ) );
 
 
66
 
67
+ if ( false == $this->options ) {
68
+ add_option( $this->option_name, $this->default_ga_values() );
69
+ $this->options = $this->get_options();
70
  }
71
 
72
+ if ( ! isset( $this->options['version'] ) || $this->options['version'] < GAWP_VERSION ) {
73
+ $this->upgrade();
 
 
 
 
 
 
 
 
 
 
74
  }
75
 
76
+ // If instance is null, create it. Prevent creating multiple instances of this class
77
+ if ( is_null( self::$instance ) ) {
78
+ self::$instance = $this;
 
 
 
 
 
 
79
  }
80
 
81
+ add_action( 'plugins_loaded', array( $this, 'load_textdomain' ) );
82
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
 
84
+ /**
85
+ * Updates the GA option within the current option_prefix
86
+ *
87
+ * @param array $val
88
+ *
89
+ * @return bool
90
+ */
91
+ public function update_option( $val ) {
92
+ $options = get_option( $this->option_name );
93
+ $options[$this->option_prefix] = $val;
94
+
95
+ return update_option( $this->option_name, $options );
96
+ }
97
 
98
+ /**
99
+ * Return the Google Analytics options
100
+ *
101
+ * @return mixed|void
102
+ */
103
+ public function get_options() {
104
+ $options = get_option( $this->option_name );
105
 
106
+ return $options[$this->option_prefix];
107
+ }
 
 
 
 
 
 
108
 
109
+ /**
110
+ * Check if all the options are set, to prevent a notice if debugging is enabled
111
+ * When we have new changes, the settings are saved to the options class
112
+ *
113
+ * @param $options
114
+ *
115
+ * @return mixed
116
+ */
117
+ public function check_options( $options ) {
118
+
119
+ $changes = 0;
120
+ foreach ( $this->default_ga_values() as $key => $value ) {
121
+ if ( ! isset( $options[$key] ) ) {
122
+ $options[$key] = $value;
123
+ $changes ++;
124
  }
125
+ }
126
 
127
+ if ( $changes >= 1 ) {
128
+ $this->update_option( $options );
129
+ }
130
+
131
+ return $options;
132
+ }
133
 
134
+ /**
135
+ * Get the Google Analytics tracking code for this website
136
+ *
137
+ * @return null
138
+ */
139
+ public function get_tracking_code() {
140
+ $tracking_code = null;
141
+ $this->options = $this->get_options();
142
+
143
+ if ( ! empty( $this->options['analytics_profile'] ) && ! empty( $this->options['analytics_profile_code'] ) ) {
144
+ $tracking_code = $this->options['analytics_profile_code'];
145
+ } elseif ( ! empty( $this->options['analytics_profile'] ) && empty( $this->options['analytics_profile_code'] ) ) {
146
+ // Analytics profile is still holding the UA code
147
+ $tracking_code = $this->options['analytics_profile'];
148
  }
149
 
150
+ if ( ! empty( $this->options['manual_ua_code_field'] ) && ! empty( $this->options['manual_ua_code'] ) ) {
151
+ $tracking_code = $this->options['manual_ua_code_field'];
152
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
 
154
+ return $tracking_code;
155
+ }
156
 
157
+ /**
158
+ * Convert a option value to a bool
159
+ *
160
+ * @param $option_name
161
+ *
162
+ * @return bool
163
+ */
164
+ public function option_value_to_bool( $option_name ) {
165
+ $this->options = $this->get_options();
166
+
167
+ if ( isset( $this->options[$option_name] ) && $this->options[$option_name] == 1 ) {
168
+ return true;
169
+ }
170
 
171
+ return false;
172
+ }
 
 
 
 
173
 
174
+ /**
175
+ * Upgrade the settings when settings are changed.
176
+ *
177
+ * @since 5.0.1
178
+ */
179
+ private function upgrade() {
180
+ if ( ! isset( $this->options['version'] ) && is_null( $this->get_tracking_code() ) ) {
181
+ $old_options = get_option( 'Yoast_Google_Analytics' );
182
+ if ( isset( $old_options ) && is_array( $old_options ) ) {
183
+ if ( isset( $old_options['uastring'] ) && '' !== trim( $old_options['uastring'] ) ) {
184
+ // Save UA as manual UA, instead of saving all the old GA crap
185
+ $this->options['manual_ua_code'] = 1;
186
+ $this->options['manual_ua_code_field'] = $old_options['uastring'];
187
  }
188
+ // Other settings
189
+ $this->options['allow_anchor'] = $old_options['allowanchor'];
190
+ $this->options['add_allow_linker'] = $old_options['allowlinker'];
191
+ $this->options['anonymous_data'] = $old_options['anonymizeip'];
192
+ $this->options['track_outbound'] = $old_options['trackoutbound'];
193
+ $this->options['track_internal_as_outbound'] = $old_options['internallink'];
194
+ $this->options['track_internal_as_label'] = $old_options['internallinklabel'];
195
+ $this->options['extensions_of_files'] = $old_options['dlextensions'];
196
  }
197
+ delete_option( 'Yoast_Google_Analytics' );
198
+ }
199
+ // 5.0.0 to 5.0.1 fix of ignore users array
200
+ if ( ! isset( $this->options['version'] ) || version_compare( $this->options['version'], '5.0.1', '<' ) ) {
201
+ if ( isset( $this->options['ignore_users'] ) && ! is_array( $this->options['ignore_users'] ) ) {
202
+ $this->options['ignore_users'] = (array) $this->options['ignore_users'];
203
  }
204
+ }
205
+ // 5.1.2+ Remove firebug_lite from options, if set
206
+ if ( ! isset ( $this->options['version'] ) || version_compare( $this->options['version'], '5.1.2', '<' ) ) {
207
+ if ( isset( $this->options['firebug_lite'] ) ) {
208
+ unset( $this->options['firebug_lite'] );
 
 
209
  }
 
 
 
 
 
210
  }
211
+ // 5.2.8+ Add disabled dashboards option
212
+ if ( ! isset ( $this->options['dashboards_disabled'] ) || version_compare( $this->options['version'], '5.2.8', '>' ) ) {
213
+ $this->options['dashboards_disabled'] = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  }
215
+ // Check is API option already exists - if not add it
216
+ $yst_ga_api = get_option( 'yst_ga_api' );
217
+ if ( $yst_ga_api === false ) {
218
+ add_option( 'yst_ga_api', array(), '', 'no' );
 
 
219
  }
220
+ // Fallback to make sure every default option has a value
221
+ $defaults = $this->default_ga_values();
222
+ foreach ( $defaults[$this->option_prefix] as $key => $value ) {
223
+ if ( ! isset( $this->options[$key] ) ) {
224
+ $this->options[$key] = $value;
225
+ }
226
+ }
227
+ // Set to the current version now that we've done all needed upgrades
228
+ $this->options['version'] = GAWP_VERSION;
229
+ $this->update_option( $this->options );
230
+ }
231
 
232
+ /**
233
+ * Set the default GA settings here
234
+ * @return array
235
+ */
236
+ public function default_ga_values() {
237
+ $options = array(
238
+ $this->option_prefix => array(
239
+ 'analytics_profile' => null,
240
+ 'analytics_profile_code' => null,
241
+ 'manual_ua_code' => 0,
242
+ 'manual_ua_code_field' => null,
243
+ 'track_internal_as_outbound' => null,
244
+ 'track_internal_as_label' => null,
245
+ 'track_outbound' => 0,
246
+ 'anonymous_data' => 0,
247
+ 'enable_universal' => 0,
248
+ 'demographics' => 0,
249
+ 'ignore_users' => array( 'editor' ),
250
+ 'dashboards_disabled' => 0,
251
+ 'anonymize_ips' => 0,
252
+ 'track_download_as' => 'event',
253
+ 'extensions_of_files' => 'doc,exe,js,pdf,ppt,tgz,zip,xls',
254
+ 'track_full_url' => 'domain',
255
+ 'subdomain_tracking' => null,
256
+ 'tag_links_in_rss' => 0,
257
+ 'allow_anchor' => 0,
258
+ 'add_allow_linker' => 0,
259
+ 'custom_code' => null,
260
+ 'debug_mode' => 0,
261
+ )
262
+ );
263
+ $options = apply_filters( 'yst_ga_default-ga-values', $options, $this->option_prefix );
264
+ return $options;
265
  }
266
+
267
+ /**
268
+ * Load plugin textdomain
269
+ */
270
+ public static function load_textdomain() {
271
+ load_plugin_textdomain( 'google-analytics-for-wordpress', false, dirname( plugin_basename( GAWP_FILE ) ) . '/languages/' );
272
+ }
273
+
274
+ }
includes/class-settings.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Yoast_GA_Settings {
4
+
5
+ /**
6
+ * Saving instance of it's own in this static var
7
+ *
8
+ * @var object
9
+ */
10
+ private static $instance;
11
+
12
+ /**
13
+ * Store the options class instance
14
+ *
15
+ * @var mixed|void
16
+ */
17
+ private $options_class;
18
+
19
+ /**
20
+ * The main GA options
21
+ *
22
+ * @var
23
+ */
24
+ private $options;
25
+
26
+ /**
27
+ * Set the options of Google Analytics
28
+ */
29
+ protected function __construct() {
30
+ $this->options_class = Yoast_GA_Options::instance();
31
+ $this->options = $this->options_class->get_options();
32
+ }
33
+
34
+ /**
35
+ * Getting instance of this object. If instance doesn't exists it will be created.
36
+ *
37
+ * @return object|Yoast_GA_Settings
38
+ */
39
+ public static function get_instance() {
40
+ if ( is_null( self::$instance ) ) {
41
+ self::$instance = new Yoast_GA_Settings();
42
+ }
43
+
44
+ return self::$instance;
45
+ }
46
+
47
+ /**
48
+ * Return the Dashboards disabled bool
49
+ *
50
+ * @return bool
51
+ */
52
+ public function dashboards_disabled() {
53
+ return $this->options_class->option_value_to_bool( 'dashboards_disabled' );
54
+ }
55
+
56
+ }
includes/class-utils.php CHANGED
@@ -1,40 +1,37 @@
1
  <?php
2
 
3
- if ( ! class_exists( 'Yoast_GA_Utils' ) ) {
4
-
5
- class Yoast_GA_Utils {
6
-
7
- /**
8
- * Check if WordPress SEO or WordPress SEO Premium is active
9
- *
10
- * @return bool
11
- */
12
- public static function wp_seo_active() {
13
- $wp_seo_active = false;
14
-
15
- //Makes sure is_plugin_active is available when called from front end
16
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
17
- if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) || is_plugin_active( 'wordpress-seo-premium/wp-seo-premium.php' ) ) {
18
- $wp_seo_active = true;
19
- }
20
-
21
- return $wp_seo_active;
22
  }
23
 
24
- /**
25
- * Calculate the date difference, return the amount of hours between the two dates
26
- *
27
- * @param $last_run datetime
28
- * @param $now datetime
29
- *
30
- * @return int
31
- */
32
- public static function hours_between( $last_run, $now ) {
33
- $seconds = max( ( $now - $last_run ), 1 );
34
- $hours = $seconds / 3600;
35
-
36
- return floor( $hours );
37
- }
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
- }
 
1
  <?php
2
 
3
+ class Yoast_GA_Utils {
4
+
5
+ /**
6
+ * Check if WordPress SEO or WordPress SEO Premium is active
7
+ *
8
+ * @return bool
9
+ */
10
+ public static function wp_seo_active() {
11
+ $wp_seo_active = false;
12
+
13
+ //Makes sure is_plugin_active is available when called from front end
14
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
15
+ if ( is_plugin_active( 'wordpress-seo/wp-seo.php' ) || is_plugin_active( 'wordpress-seo-premium/wp-seo-premium.php' ) ) {
16
+ $wp_seo_active = true;
 
 
 
 
 
17
  }
18
 
19
+ return $wp_seo_active;
20
+ }
 
 
 
 
 
 
 
 
 
 
 
 
21
 
22
+ /**
23
+ * Calculate the date difference, return the amount of hours between the two dates
24
+ *
25
+ * @param $last_run datetime
26
+ * @param $now datetime
27
+ *
28
+ * @return int
29
+ */
30
+ public static function hours_between( $last_run, $now ) {
31
+ $seconds = max( ( $now - $last_run ), 1 );
32
+ $hours = $seconds / 3600;
33
+
34
+ return floor( $hours );
35
  }
36
+
37
+ }
languages/google-analytics-for-wordpress-da_DK.mo ADDED
Binary file
languages/google-analytics-for-wordpress-en_GB.mo CHANGED
Binary file
languages/google-analytics-for-wordpress-es_MX.mo ADDED
Binary file
languages/google-analytics-for-wordpress-fr_FR.mo ADDED
Binary file
languages/google-analytics-for-wordpress-he_IL.mo CHANGED
Binary file
languages/google-analytics-for-wordpress-it_IT.mo ADDED
Binary file
languages/google-analytics-for-wordpress-nb_NO.mo ADDED
Binary file
languages/google-analytics-for-wordpress-nl_NL.mo CHANGED
Binary file
languages/google-analytics-for-wordpress-pl_PL.mo ADDED
Binary file
languages/google-analytics-for-wordpress-pt_BR.mo ADDED
Binary file
languages/google-analytics-for-wordpress-ru_RU.mo CHANGED
Binary file
languages/google-analytics-for-wordpress.pot CHANGED
@@ -1,15 +1,15 @@
1
- # Copyright (C) 2014 Team Yoast
2
  # This file is distributed under the GPL v3.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: Google Analytics by Yoast 5.1.4\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://github.com/yoast/google-analytics-for-wordpress/issues\n"
8
- "POT-Creation-Date: 2014-12-02 13:22:29+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
- "PO-Revision-Date: 2014-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: Yoast Translate Team <translations@yoast.com>\n"
14
  "Language-Team: Yoast Translate <translations@yoast.com>\n"
15
  "X-Generator: grunt-wp-i18n 0.4.9\n"
@@ -25,79 +25,222 @@ msgstr ""
25
  "X-Poedit-Bookmarks: \n"
26
  "X-Textdomain-Support: yes\n"
27
 
28
- #: admin/class-admin-menu.php:55 admin/class-admin-menu.php:79
29
  msgid "Yoast Google Analytics:"
30
  msgstr ""
31
 
32
- #: admin/class-admin-menu.php:55 admin/pages/settings.php:28
33
  msgid "General settings"
34
  msgstr ""
35
 
36
- #: admin/class-admin-menu.php:55
37
  msgid "Analytics"
38
  msgstr ""
39
 
40
- #: admin/class-admin.php:76
41
- msgid "Please configure your %sGoogle Analytics settings%s!"
 
42
  msgstr ""
43
 
44
- #: admin/class-admin.php:106
45
- msgid "Settings saved!"
46
  msgstr ""
47
 
48
- #: admin/class-admin.php:113
49
- msgid "There where no changes to save, please try again."
 
50
  msgstr ""
51
 
52
- #: admin/class-admin.php:132
53
- msgid "FAQ"
54
  msgstr ""
55
 
56
- #: admin/class-admin.php:135 admin/pages/settings.php:6
57
- msgid "Settings"
58
  msgstr ""
59
 
60
- #: admin/class-admin.php:188
 
 
 
 
61
  msgid ""
62
- "If you want to track custom dimensions, to for instance track page views "
63
- "per author or post type, you should upgrade to the %1$spremium version of "
64
- "Google Analytics by Yoast%2$s."
65
  msgstr ""
66
 
67
- #: admin/class-admin.php:190
68
  msgid ""
69
  "This will also give you email access to the support team at Yoast, who will "
70
  "provide support on the plugin 24/7."
71
  msgstr ""
72
 
73
- #: admin/class-admin.php:543
74
  msgid "Debug information"
75
  msgstr ""
76
 
77
- #: admin/class-admin.php:592
78
  msgid "Google Analytics by Yoast Premium"
79
  msgstr ""
80
 
81
- #: admin/class-admin.php:593
82
  msgid ""
83
- "The premium version of Google Analytics for WordPress with more features "
84
- "&amp; support."
85
  msgstr ""
86
 
87
- #: admin/class-admin.php:598
88
- msgid "Google Analytics"
89
  msgstr ""
90
 
91
- #: admin/class-admin.php:598
92
- msgid "E-Commerce tracking"
93
  msgstr ""
94
 
95
- #: admin/class-admin.php:599
96
  msgid ""
97
- "Track your E-Commerce data and transactions with this E-Commerce extension "
98
  "for Google Analytics."
99
  msgstr ""
100
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  #: admin/i18n-module/i18n-module.php:170
102
  msgid ""
103
  "As you can see, there is a translation of this plugin in %1$s. This "
@@ -273,24 +416,38 @@ msgstr ""
273
  msgid "%sRenew your license now%s."
274
  msgstr ""
275
 
276
- #: admin/pages/dashboard.php:6 admin/pages/extensions.php:10
277
  #: admin/pages/settings.php:6
278
- msgid "Yoast Google Analytics: "
279
  msgstr ""
280
 
281
- #: admin/pages/dashboard.php:6
282
- msgid "Dashboard"
283
  msgstr ""
284
 
285
- #: admin/pages/dashboard.php:9
286
  msgid ""
287
- "This feature %1$swill be coming soon%2$s. For now, you can %3$sread our "
288
- "posts on Analytics%2$s, or of course, %4$slog into Google Analytics%2$s "
289
- "yourself."
290
  msgstr ""
291
 
292
- #: admin/pages/extensions.php:10 admin/pages/extensions.php:13
293
- msgid "Extensions"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
  msgstr ""
295
 
296
  #: admin/pages/extensions.php:14
@@ -299,8 +456,8 @@ msgstr ""
299
 
300
  #: admin/pages/extensions.php:58
301
  msgid ""
302
- "You have not installed any extensions for Yoast Google Analytics, so there "
303
- "are no licenses to activate."
304
  msgstr ""
305
 
306
  #: admin/pages/settings.php:13
@@ -315,200 +472,266 @@ msgstr ""
315
  msgid "Advanced"
316
  msgstr ""
317
 
318
- #: admin/pages/settings.php:16 admin/pages/settings.php:102
319
- msgid "Custom dimensions"
320
  msgstr ""
321
 
322
  #: admin/pages/settings.php:18
323
  msgid "Debug mode"
324
  msgstr ""
325
 
326
- #: admin/pages/settings.php:41
 
 
 
 
327
  msgid "Google profile"
328
  msgstr ""
329
 
330
- #: admin/pages/settings.php:42
331
  msgid "Authenticate with your Google account"
332
  msgstr ""
333
 
334
- #: admin/pages/settings.php:45
335
  msgid "Current UA-profile"
336
  msgstr ""
337
 
338
- #: admin/pages/settings.php:53
339
- msgid "Re-authenticate with your Google account"
 
 
 
 
340
  msgstr ""
341
 
342
  #: admin/pages/settings.php:59
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
343
  msgid "Manually enter your UA code"
344
  msgstr ""
345
 
346
- #: admin/pages/settings.php:68
347
- msgid "Track outbound click & downloads"
 
 
 
 
 
 
348
  msgstr ""
349
 
350
- #: admin/pages/settings.php:68
351
  msgid ""
352
- "Clicks &amp; downloads will be tracked as events, you can find these under "
353
- "Content &raquo; Event Tracking in your Google Analytics reports."
354
  msgstr ""
355
 
356
- #: admin/pages/settings.php:69
357
  msgid "Allow tracking of anonymous data"
358
  msgstr ""
359
 
360
- #: admin/pages/settings.php:69
361
  msgid ""
362
  "By allowing us to track anonymous data we can better help you, because we "
363
  "know with which WordPress configurations, themes and plugins we should "
364
  "test. No personal data will be submitted."
365
  msgstr ""
366
 
367
- #: admin/pages/settings.php:70
368
- msgid "Anonymize IP's"
369
  msgstr ""
370
 
371
- #: admin/pages/settings.php:70
372
  msgid ""
373
- "This adds <code>%1$s _anonymizeIp%2$s</code>, telling Google Analytics to "
374
- "anonymize the information sent by the tracker objects by removing the last "
375
- "octet of the IP address prior to its storage."
376
  msgstr ""
377
 
378
- #: admin/pages/settings.php:71
379
  msgid ""
380
  "Users of the role you select will be ignored, so if you select Editor, all "
381
  "Editors will be ignored."
382
  msgstr ""
383
 
384
- #: admin/pages/settings.php:76
 
 
 
 
 
 
 
 
 
 
385
  msgid "Universal settings"
386
  msgstr ""
387
 
388
- #: admin/pages/settings.php:77
389
  msgid "Enable Universal tracking"
390
  msgstr ""
391
 
392
- #: admin/pages/settings.php:77
393
  msgid ""
394
- "First enable Universal tracking in your Google Analytics account. How to do "
395
- "that, please read %1$sthis guide%2$s to learn how to do that."
396
  msgstr ""
397
 
398
- #: admin/pages/settings.php:78
399
  msgid "Enable Demographics and Interest Reports"
400
  msgstr ""
401
 
402
- #: admin/pages/settings.php:78
403
  msgid ""
404
  "You have to enable the Demographics in Google Analytics before you can see "
405
- "the tracking data. We have a doc in our %1$sknowlegde base%2$s about this "
406
- "feature."
407
  msgstr ""
408
 
409
- #: admin/pages/settings.php:83
410
  msgid "Advanced settings"
411
  msgstr ""
412
 
413
- #: admin/pages/settings.php:84
414
  msgid "Track downloads as"
415
  msgstr ""
416
 
417
- #: admin/pages/settings.php:84
418
  msgid ""
419
  "Not recommended, as this would skew your statistics, but it does make it "
420
  "possible to track downloads as goals."
421
  msgstr ""
422
 
423
- #: admin/pages/settings.php:85
424
  msgid "Extensions of files to track as downloads"
425
  msgstr ""
426
 
427
- #: admin/pages/settings.php:86
428
  msgid "Track full URL of outbound clicks or just the domain"
429
  msgstr ""
430
 
431
- #: admin/pages/settings.php:87
432
  msgid "Subdomain tracking"
433
  msgstr ""
434
 
435
- #: admin/pages/settings.php:87
436
  msgid ""
437
- "This allows you to set the domain that's set by <code>setDomainName</code> "
438
- "for tracking subdomains, if empty this will not be set."
439
  msgstr ""
440
 
441
- #: admin/pages/settings.php:89
442
  msgid "Set path for internal links to track as outbound links"
443
  msgstr ""
444
 
445
- #: admin/pages/settings.php:90
 
 
 
 
 
 
 
446
  msgid "Label for those links"
447
  msgstr ""
448
 
449
- #: admin/pages/settings.php:92
450
  msgid "Tag links in RSS feed with campaign variables"
451
  msgstr ""
452
 
453
- #: admin/pages/settings.php:92
454
  msgid ""
455
  "Do not use this feature if you use FeedBurner, as FeedBurner can do this "
456
- "automatically, and better than this plugin can. Check <a "
457
  "href=\"https://support.google.com/feedburner/answer/165769?hl=en&amp;ref_"
458
  "topic=13075\" target=\"_blank\">this help page</a> for info on how to "
459
  "enable this feature in FeedBurner."
460
  msgstr ""
461
 
462
- #: admin/pages/settings.php:93
463
  msgid "Allow anchor"
464
  msgstr ""
465
 
466
- #: admin/pages/settings.php:93
467
  msgid ""
468
- "This adds a <code>%1$s_setAllowAnchor%2$s</code> call to your tracking "
469
- "code, and makes RSS link tagging use a # as well."
470
  msgstr ""
471
 
472
- #: admin/pages/settings.php:94
473
  msgid "Add <code>_setAllowLinker</code>"
474
  msgstr ""
475
 
476
- #: admin/pages/settings.php:94
477
  msgid ""
478
- "This adds a <code>%1$s_setAllowLinker%2$s</code> call to your tracking "
479
- "code, allowing you to use <code>_link</code> and related functions."
480
  msgstr ""
481
 
482
- #: admin/pages/settings.php:95
483
  msgid ""
484
  "Not for the average user: this allows you to add a line of code, to be "
485
- "added before the <code>trackPageview</code> call."
486
  msgstr ""
487
 
488
- #: admin/pages/settings.php:109
489
- msgid "Debug settings"
490
  msgstr ""
491
 
492
- #: admin/pages/settings.php:112
 
 
 
 
493
  msgid ""
494
  "If you want to confirm that tracking on your blog is working as it should, "
495
  "enable this option and check the console of your browser. Be absolutely "
496
  "sure to disable debugging afterwards, as it is slower than normal tracking."
497
  msgstr ""
498
 
499
- #: admin/pages/settings.php:113
500
- msgid "Note"
501
- msgstr ""
502
-
503
- #: admin/pages/settings.php:113
504
- msgid "the debugging scripts is only loaded for admins."
505
  msgstr ""
506
 
507
- #: admin/pages/settings.php:115
508
  msgid "Enable debug mode"
509
  msgstr ""
510
 
511
- #: admin/pages/settings.php:127
512
  msgid "Select the users to ignore"
513
  msgstr ""
514
 
@@ -520,10 +743,6 @@ msgstr ""
520
  msgid "Upgrade to Google Analytics By Yoast Premium »"
521
  msgstr ""
522
 
523
- #. Plugin Name of the plugin/theme
524
- msgid "Google Analytics by Yoast"
525
- msgstr ""
526
-
527
  #. Plugin URI of the plugin/theme
528
  msgid ""
529
  "https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&"
@@ -532,9 +751,9 @@ msgstr ""
532
 
533
  #. Description of the plugin/theme
534
  msgid ""
535
- "This plugin makes it simple to add Google Analytics to your WordPress blog, "
536
- "adding lots of features, eg. error page, search result and automatic "
537
- "clickout and download tracking."
538
  msgstr ""
539
 
540
  #. Author of the plugin/theme
@@ -543,4 +762,23 @@ msgstr ""
543
 
544
  #. Author URI of the plugin/theme
545
  msgid "https://yoast.com/"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
546
  msgstr ""
1
+ # Copyright (C) 2015 Team Yoast
2
  # This file is distributed under the GPL v3.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: Google Analytics by Yoast 5.3\n"
6
  "Report-Msgid-Bugs-To: "
7
  "https://github.com/yoast/google-analytics-for-wordpress/issues\n"
8
+ "POT-Creation-Date: 2015-01-27 12:07:54+00:00\n"
9
  "MIME-Version: 1.0\n"
10
  "Content-Type: text/plain; charset=utf-8\n"
11
  "Content-Transfer-Encoding: 8bit\n"
12
+ "PO-Revision-Date: 2015-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: Yoast Translate Team <translations@yoast.com>\n"
14
  "Language-Team: Yoast Translate <translations@yoast.com>\n"
15
  "X-Generator: grunt-wp-i18n 0.4.9\n"
25
  "X-Poedit-Bookmarks: \n"
26
  "X-Textdomain-Support: yes\n"
27
 
28
+ #: admin/class-admin-menu.php:65 admin/class-admin-menu.php:126
29
  msgid "Yoast Google Analytics:"
30
  msgstr ""
31
 
32
+ #: admin/class-admin-menu.php:65 admin/pages/settings.php:28
33
  msgid "General settings"
34
  msgstr ""
35
 
36
+ #: admin/class-admin-menu.php:65
37
  msgid "Analytics"
38
  msgstr ""
39
 
40
+ #: admin/class-admin-menu.php:210 admin/pages/extensions.php:10
41
+ #: admin/pages/extensions.php:13
42
+ msgid "Extensions"
43
  msgstr ""
44
 
45
+ #: admin/class-admin-menu.php:218 admin/pages/dashboard.php:10
46
+ msgid "Dashboard"
47
  msgstr ""
48
 
49
+ #: admin/class-admin-menu.php:221 admin/class-admin.php:204
50
+ #: admin/pages/settings.php:6
51
+ msgid "Settings"
52
  msgstr ""
53
 
54
+ #: admin/class-admin.php:119
55
+ msgid "Settings saved."
56
  msgstr ""
57
 
58
+ #: admin/class-admin.php:126
59
+ msgid "There were no changes to save, please try again."
60
  msgstr ""
61
 
62
+ #: admin/class-admin.php:201
63
+ msgid "FAQ"
64
+ msgstr ""
65
+
66
+ #: admin/class-admin.php:216
67
  msgid ""
68
+ "If you want to track custom dimensions like page views per author or post "
69
+ "type, you should upgrade to the %1$spremium version of Google Analytics by "
70
+ "Yoast%2$s."
71
  msgstr ""
72
 
73
+ #: admin/class-admin.php:218
74
  msgid ""
75
  "This will also give you email access to the support team at Yoast, who will "
76
  "provide support on the plugin 24/7."
77
  msgstr ""
78
 
79
+ #: admin/class-admin.php:388
80
  msgid "Debug information"
81
  msgstr ""
82
 
83
+ #: admin/class-admin.php:437
84
  msgid "Google Analytics by Yoast Premium"
85
  msgstr ""
86
 
87
+ #: admin/class-admin.php:438
88
  msgid ""
89
+ "The premium version of Google Analytics by Yoast with more features and "
90
+ "support."
91
  msgstr ""
92
 
93
+ #. Plugin Name of the plugin/theme
94
+ msgid "Google Analytics by Yoast"
95
  msgstr ""
96
 
97
+ #: admin/class-admin.php:443
98
+ msgid "eCommerce tracking"
99
  msgstr ""
100
 
101
+ #: admin/class-admin.php:444
102
  msgid ""
103
+ "Track your eCommerce data and transactions with this eCommerce extension "
104
  "for Google Analytics."
105
  msgstr ""
106
 
107
+ #: admin/class-google-analytics.php:311
108
+ msgid "Please configure your %sGoogle Analytics settings%s!"
109
+ msgstr ""
110
+
111
+ #: admin/class-google-analytics.php:324
112
+ msgid ""
113
+ "It seems the authentication for the plugin has expired, please "
114
+ "%sre-authenticate%s with Google Analytics to allow the plugin to fetch data."
115
+ msgstr ""
116
+
117
+ #: admin/class-google-analytics.php:337
118
+ msgid ""
119
+ "Data is not up-to-date, there was an error in retrieving the data from "
120
+ "Google Analytics. This error could be caused by several issues. If the "
121
+ "error persists, please see %sthis page%s."
122
+ msgstr ""
123
+
124
+ #: admin/dashboards/class-admin-dashboards.php:137
125
+ msgid ": activate to sort column ascending"
126
+ msgstr ""
127
+
128
+ #: admin/dashboards/class-admin-dashboards.php:138
129
+ msgid ": activate to sort column descending"
130
+ msgstr ""
131
+
132
+ #: admin/dashboards/class-admin-dashboards.php:139
133
+ msgid "No data available"
134
+ msgstr ""
135
+
136
+ #: admin/dashboards/class-admin-dashboards.php:141
137
+ msgid "No rows to show"
138
+ msgstr ""
139
+
140
+ #: admin/dashboards/class-admin-dashboards.php:144
141
+ msgid "Loading..."
142
+ msgstr ""
143
+
144
+ #: admin/dashboards/class-admin-dashboards.php:145
145
+ msgid "First"
146
+ msgstr ""
147
+
148
+ #: admin/dashboards/class-admin-dashboards.php:146
149
+ msgid "Last"
150
+ msgstr ""
151
+
152
+ #: admin/dashboards/class-admin-dashboards.php:147
153
+ msgid "Next"
154
+ msgstr ""
155
+
156
+ #: admin/dashboards/class-admin-dashboards.php:148
157
+ msgid "Previous"
158
+ msgstr ""
159
+
160
+ #: admin/dashboards/class-admin-dashboards.php:149
161
+ msgid "Processing..."
162
+ msgstr ""
163
+
164
+ #: admin/dashboards/class-admin-dashboards.php:150
165
+ msgid "Search"
166
+ msgstr ""
167
+
168
+ #: admin/dashboards/class-admin-dashboards.php:151
169
+ msgid "No matching records found"
170
+ msgstr ""
171
+
172
+ #: admin/dashboards/class-admin-dashboards.php:154 admin/pages/dashboard.php:14
173
+ msgid "Reports"
174
+ msgstr ""
175
+
176
+ #: admin/dashboards/class-admin-dashboards.php:155 admin/pages/dashboard.php:15
177
+ msgid "Custom dimension reports"
178
+ msgstr ""
179
+
180
+ #: admin/dashboards/class-admin-dashboards.php:193
181
+ #: admin/dashboards/class-admin-dashboards.php:210
182
+ #: admin/dashboards/class-admin-dashboards.php:219
183
+ #: admin/dashboards/class-admin-dashboards.php:228
184
+ msgid "Sessions"
185
+ msgstr ""
186
+
187
+ #: admin/dashboards/class-admin-dashboards.php:194
188
+ msgid ""
189
+ "A session is a group of interactions that take place on your website within "
190
+ "a given time frame. For example a single session can contain multiple "
191
+ "screen or page views, events, social interactions, and ecommerce "
192
+ "transactions. <a href=\"http://yoa.st/gasessions\" target=\"_blank\">[Learn "
193
+ "more]</a>"
194
+ msgstr ""
195
+
196
+ #: admin/dashboards/class-admin-dashboards.php:199
197
+ msgid "Bounce rate"
198
+ msgstr ""
199
+
200
+ #: admin/dashboards/class-admin-dashboards.php:200
201
+ msgid ""
202
+ "Bounce Rate is the percentage of single-page sessions (i.e. sessions in "
203
+ "which the person left your site from the entrance page without interacting "
204
+ "with the page). <a href=\"http://yoa.st/gabounce\" target=\"_blank\">[Learn "
205
+ "more]</a>"
206
+ msgstr ""
207
+
208
+ #: admin/dashboards/class-admin-dashboards.php:206
209
+ msgid "Traffic sources"
210
+ msgstr ""
211
+
212
+ #: admin/dashboards/class-admin-dashboards.php:207
213
+ msgid ""
214
+ "Every referral to a web site has an origin, or (traffic) source. Possible "
215
+ "sources include: “google” (the name of a search engine), “facebook.com” "
216
+ "(the name of a referring site), “spring_newsletter” (the name of one of "
217
+ "your newsletters), and “direct” (users that typed your URL directly into "
218
+ "their browser, or who had bookmarked your site). <a "
219
+ "href=\"http://yoa.st/gabnce\" target=\"_blank\">[Learn more]</a>"
220
+ msgstr ""
221
+
222
+ #: admin/dashboards/class-admin-dashboards.php:215
223
+ msgid "Popular pages"
224
+ msgstr ""
225
+
226
+ #: admin/dashboards/class-admin-dashboards.php:216
227
+ msgid "Pages by url."
228
+ msgstr ""
229
+
230
+ #: admin/dashboards/class-admin-dashboards.php:224
231
+ msgid "Countries"
232
+ msgstr ""
233
+
234
+ #: admin/dashboards/class-admin-dashboards.php:225
235
+ msgid ""
236
+ "The country or territory from which visits originated. <a "
237
+ "href=\"http://yoa.st/gacountry\" target=\"_blank\">[Learn more]</a>"
238
+ msgstr ""
239
+
240
+ #: admin/dashboards/views/graph.php:9 admin/dashboards/views/table.php:9
241
+ msgid "Last month"
242
+ msgstr ""
243
+
244
  #: admin/i18n-module/i18n-module.php:170
245
  msgid ""
246
  "As you can see, there is a translation of this plugin in %1$s. This "
416
  msgid "%sRenew your license now%s."
417
  msgstr ""
418
 
419
+ #: admin/pages/dashboard.php:10 admin/pages/extensions.php:10
420
  #: admin/pages/settings.php:6
421
+ msgid "Google Analytics by Yoast: "
422
  msgstr ""
423
 
424
+ #: admin/pages/dashboard.php:13
425
+ msgid "Overview"
426
  msgstr ""
427
 
428
+ #: admin/pages/dashboard.php:39 admin/pages/dashboard.php:75
429
  msgid ""
430
+ "We need you to authenticate with Google Analytics to use this "
431
+ "functionality. If you set your UA-code manually, this won't work. You can "
432
+ "%sauthenticate your Google Analytics profile here%s to enable dashboards."
433
  msgstr ""
434
 
435
+ #: admin/pages/dashboard.php:47 admin/pages/dashboard.php:83
436
+ msgid ""
437
+ "Because we've switched to a newer version of the Google Analytics API, "
438
+ "you'll need to re-authenticate with Google Analytics. We're sorry for the "
439
+ "inconvenience. You can %sre-authenticate your Google Analytics profile "
440
+ "here%s."
441
+ msgstr ""
442
+
443
+ #: admin/pages/dashboard.php:58 admin/pages/dashboard.php:101
444
+ msgid ""
445
+ "You have not yet finished setting up Google Analytics for Wordpress by "
446
+ "Yoast. Please %sadd your Analytics profile here%s to enable tracking."
447
+ msgstr ""
448
+
449
+ #: admin/pages/dashboard.php:91
450
+ msgid "Select a dimension"
451
  msgstr ""
452
 
453
  #: admin/pages/extensions.php:14
456
 
457
  #: admin/pages/extensions.php:58
458
  msgid ""
459
+ "You have not installed any extensions for Google Analytics by Yoast, so "
460
+ "there are no licenses to activate."
461
  msgstr ""
462
 
463
  #: admin/pages/settings.php:13
472
  msgid "Advanced"
473
  msgstr ""
474
 
475
+ #: admin/pages/settings.php:16
476
+ msgid "Custom Dimensions"
477
  msgstr ""
478
 
479
  #: admin/pages/settings.php:18
480
  msgid "Debug mode"
481
  msgstr ""
482
 
483
+ #: admin/pages/settings.php:42
484
+ msgid "Paste your Google authentication code"
485
+ msgstr ""
486
+
487
+ #: admin/pages/settings.php:47
488
  msgid "Google profile"
489
  msgstr ""
490
 
491
+ #: admin/pages/settings.php:48
492
  msgid "Authenticate with your Google account"
493
  msgstr ""
494
 
495
+ #: admin/pages/settings.php:51
496
  msgid "Current UA-profile"
497
  msgstr ""
498
 
499
+ #: admin/pages/settings.php:55
500
+ msgid "Analytics profile"
501
+ msgstr ""
502
+
503
+ #: admin/pages/settings.php:55
504
+ msgid "Select a profile"
505
  msgstr ""
506
 
507
  #: admin/pages/settings.php:59
508
+ msgid "Re-authenticate with your Google account"
509
+ msgstr ""
510
+
511
+ #: admin/pages/settings.php:65
512
+ msgid "Paste your Google code here"
513
+ msgstr ""
514
+
515
+ #: admin/pages/settings.php:69
516
+ msgid "Save authentication code"
517
+ msgstr ""
518
+
519
+ #: admin/pages/settings.php:72
520
+ msgid "Cannot connect to Google"
521
+ msgstr ""
522
+
523
+ #: admin/pages/settings.php:74
524
+ msgid ""
525
+ "Your server is blocking requests to Google, to fix this, add "
526
+ "<code>*.googleapis.com</code> to the <code>WP_ACCESSIBLE_HOSTS</code> "
527
+ "constant in your <em>wp-config.php</em> or ask your webhost to do this."
528
+ msgstr ""
529
+
530
+ #: admin/pages/settings.php:76
531
+ msgid ""
532
+ "Your firewall or webhost is blocking requests to Google, please ask your "
533
+ "webhost company to fix this."
534
+ msgstr ""
535
+
536
+ #: admin/pages/settings.php:78
537
+ msgid ""
538
+ "Until this is fixed, you can only use the manual authentication method and "
539
+ "cannot use the dashboards feature."
540
+ msgstr ""
541
+
542
+ #: admin/pages/settings.php:82
543
  msgid "Manually enter your UA code"
544
  msgstr ""
545
 
546
+ #: admin/pages/settings.php:86
547
+ msgid ""
548
+ "Warning: If you use a manual UA code, you won't be able to use the "
549
+ "dashboards."
550
+ msgstr ""
551
+
552
+ #: admin/pages/settings.php:92
553
+ msgid "Track outbound click and downloads"
554
  msgstr ""
555
 
556
+ #: admin/pages/settings.php:92
557
  msgid ""
558
+ "Clicks and downloads will be tracked as events, you can find these under "
559
+ "Content &#xBB; Event Tracking in your Google Analytics reports."
560
  msgstr ""
561
 
562
+ #: admin/pages/settings.php:93
563
  msgid "Allow tracking of anonymous data"
564
  msgstr ""
565
 
566
+ #: admin/pages/settings.php:93
567
  msgid ""
568
  "By allowing us to track anonymous data we can better help you, because we "
569
  "know with which WordPress configurations, themes and plugins we should "
570
  "test. No personal data will be submitted."
571
  msgstr ""
572
 
573
+ #: admin/pages/settings.php:94
574
+ msgid "Anonymize IPs"
575
  msgstr ""
576
 
577
+ #: admin/pages/settings.php:94
578
  msgid ""
579
+ "This adds %1$s, telling Google Analytics to anonymize the information sent "
580
+ "by the tracker objects by removing the last octet of the IP address prior "
581
+ "to its storage."
582
  msgstr ""
583
 
584
+ #: admin/pages/settings.php:95
585
  msgid ""
586
  "Users of the role you select will be ignored, so if you select Editor, all "
587
  "Editors will be ignored."
588
  msgstr ""
589
 
590
+ #: admin/pages/settings.php:96
591
+ msgid "Disable analytics dashboard"
592
+ msgstr ""
593
+
594
+ #: admin/pages/settings.php:96
595
+ msgid ""
596
+ "This will completely disable the dashboard and stop the plugin from "
597
+ "fetching the latest analytics data."
598
+ msgstr ""
599
+
600
+ #: admin/pages/settings.php:101
601
  msgid "Universal settings"
602
  msgstr ""
603
 
604
+ #: admin/pages/settings.php:102
605
  msgid "Enable Universal tracking"
606
  msgstr ""
607
 
608
+ #: admin/pages/settings.php:102
609
  msgid ""
610
+ "First enable Universal tracking in your Google Analytics account. Please "
611
+ "read %1$sthis guide%2$s to learn how to do that."
612
  msgstr ""
613
 
614
+ #: admin/pages/settings.php:103
615
  msgid "Enable Demographics and Interest Reports"
616
  msgstr ""
617
 
618
+ #: admin/pages/settings.php:103
619
  msgid ""
620
  "You have to enable the Demographics in Google Analytics before you can see "
621
+ "the tracking data. We have a knowledge base article in our %1$sknowledge "
622
+ "base%2$s about this feature."
623
  msgstr ""
624
 
625
+ #: admin/pages/settings.php:108
626
  msgid "Advanced settings"
627
  msgstr ""
628
 
629
+ #: admin/pages/settings.php:109
630
  msgid "Track downloads as"
631
  msgstr ""
632
 
633
+ #: admin/pages/settings.php:109
634
  msgid ""
635
  "Not recommended, as this would skew your statistics, but it does make it "
636
  "possible to track downloads as goals."
637
  msgstr ""
638
 
639
+ #: admin/pages/settings.php:110
640
  msgid "Extensions of files to track as downloads"
641
  msgstr ""
642
 
643
+ #: admin/pages/settings.php:111
644
  msgid "Track full URL of outbound clicks or just the domain"
645
  msgstr ""
646
 
647
+ #: admin/pages/settings.php:112
648
  msgid "Subdomain tracking"
649
  msgstr ""
650
 
651
+ #: admin/pages/settings.php:112
652
  msgid ""
653
+ "This allows you to set the domain that's set by %1$s for tracking "
654
+ "subdomains.<br/>If empty, this will not be set."
655
  msgstr ""
656
 
657
+ #: admin/pages/settings.php:114
658
  msgid "Set path for internal links to track as outbound links"
659
  msgstr ""
660
 
661
+ #: admin/pages/settings.php:114
662
+ msgid ""
663
+ "If you want to track all internal links that begin with %1$s, enter %1$s in "
664
+ "the box above. If you have multiple prefixes you can separate them with "
665
+ "comma's: %2$s"
666
+ msgstr ""
667
+
668
+ #: admin/pages/settings.php:115
669
  msgid "Label for those links"
670
  msgstr ""
671
 
672
+ #: admin/pages/settings.php:117
673
  msgid "Tag links in RSS feed with campaign variables"
674
  msgstr ""
675
 
676
+ #: admin/pages/settings.php:117
677
  msgid ""
678
  "Do not use this feature if you use FeedBurner, as FeedBurner can do this "
679
+ "automatically and better than this plugin can. Check <a "
680
  "href=\"https://support.google.com/feedburner/answer/165769?hl=en&amp;ref_"
681
  "topic=13075\" target=\"_blank\">this help page</a> for info on how to "
682
  "enable this feature in FeedBurner."
683
  msgstr ""
684
 
685
+ #: admin/pages/settings.php:118
686
  msgid "Allow anchor"
687
  msgstr ""
688
 
689
+ #: admin/pages/settings.php:118
690
  msgid ""
691
+ "This adds a %1$s call to your tracking code, and makes RSS link tagging use "
692
+ "a %2$s as well."
693
  msgstr ""
694
 
695
+ #: admin/pages/settings.php:119
696
  msgid "Add <code>_setAllowLinker</code>"
697
  msgstr ""
698
 
699
+ #: admin/pages/settings.php:119
700
  msgid ""
701
+ "This adds a %1$s call to your tracking code, allowing you to use %2$s and "
702
+ "related functions."
703
  msgstr ""
704
 
705
+ #: admin/pages/settings.php:120
706
  msgid ""
707
  "Not for the average user: this allows you to add a line of code, to be "
708
+ "added before the %1$s call."
709
  msgstr ""
710
 
711
+ #: admin/pages/settings.php:127
712
+ msgid "Custom dimensions"
713
  msgstr ""
714
 
715
+ #: admin/pages/settings.php:134
716
+ msgid "Debug"
717
+ msgstr ""
718
+
719
+ #: admin/pages/settings.php:137
720
  msgid ""
721
  "If you want to confirm that tracking on your blog is working as it should, "
722
  "enable this option and check the console of your browser. Be absolutely "
723
  "sure to disable debugging afterwards, as it is slower than normal tracking."
724
  msgstr ""
725
 
726
+ #: admin/pages/settings.php:138
727
+ msgid "<strong>Note</strong> the debugging is only loaded for administrators."
 
 
 
 
728
  msgstr ""
729
 
730
+ #: admin/pages/settings.php:140
731
  msgid "Enable debug mode"
732
  msgstr ""
733
 
734
+ #: admin/pages/settings.php:154
735
  msgid "Select the users to ignore"
736
  msgstr ""
737
 
743
  msgid "Upgrade to Google Analytics By Yoast Premium »"
744
  msgstr ""
745
 
 
 
 
 
746
  #. Plugin URI of the plugin/theme
747
  msgid ""
748
  "https://yoast.com/wordpress/plugins/google-analytics/#utm_source=wordpress&"
751
 
752
  #. Description of the plugin/theme
753
  msgid ""
754
+ "This plugin makes it simple to add Google Analytics to your WordPress site, "
755
+ "adding lots of features, e.g. error page, search result and automatic "
756
+ "outgoing links and download tracking."
757
  msgstr ""
758
 
759
  #. Author of the plugin/theme
762
 
763
  #. Author URI of the plugin/theme
764
  msgid "https://yoast.com/"
765
+ msgstr ""
766
+
767
+ #: admin/dashboards/class-admin-dashboards.php:140
768
+ msgctxt ""
769
+ "_START_, _END_ and _TOTAL_ will be replaced by JS (See: "
770
+ "http://datatables.net/reference/option/language.info)"
771
+ msgid "Showing _START_ to _END_ of _TOTAL_ rows"
772
+ msgstr ""
773
+
774
+ #: admin/dashboards/class-admin-dashboards.php:142
775
+ msgctxt ""
776
+ "_MAX_ will be replaced by JS (See: "
777
+ "http://datatables.net/reference/option/language.infoFiltered)"
778
+ msgid "(filtered from _MAX_ total rows)"
779
+ msgstr ""
780
+
781
+ #: admin/dashboards/class-admin-dashboards.php:143
782
+ msgctxt "_MAX_ will be replaced by JS"
783
+ msgid "Show _MENU_ rows"
784
  msgstr ""
readme.txt CHANGED
@@ -1,10 +1,10 @@
1
  === Google Analytics by Yoast ===
2
- Contributors: joostdevalk,PvW_NL
3
  Donate link: https://yoast.com/donate/
4
  Tags: analytics, google analytics, statistics, tracking, stats, google, yoast
5
  Requires at least: 3.8
6
  Tested up to: 4.1
7
- Stable tag: 5.2.8
8
 
9
  Track your WordPress site easily with the latest tracking codes and lots added data for search result pages and error pages.
10
 
@@ -49,6 +49,28 @@ This section describes how to install the plugin and get it working.
49
 
50
  == Changelog ==
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  = 5.2.8 =
53
 
54
  Release Date: January 8th, 2015
1
  === Google Analytics by Yoast ===
2
+ Contributors: joostdevalk
3
  Donate link: https://yoast.com/donate/
4
  Tags: analytics, google analytics, statistics, tracking, stats, google, yoast
5
  Requires at least: 3.8
6
  Tested up to: 4.1
7
+ Stable tag: 5.3
8
 
9
  Track your WordPress site easily with the latest tracking codes and lots added data for search result pages and error pages.
10
 
49
 
50
  == Changelog ==
51
 
52
+ = 5.3 =
53
+
54
+ Release Date: January 27th, 2015
55
+
56
+ * Enhancements:
57
+ * Added an option for entirely disabling the dashboards functionality. If a user disables the dashboard, the menu item gets moved downward since there no longer is a reason for putting it so far up.
58
+ * Improved performance by making sure everything is autoloaded correctly and removing class inclusion checks everywhere.
59
+ * Makes sure the menu items become translatable.
60
+ * Added a button to save the GA authentication code as an alternative to hitting the return button.
61
+ * Format the page views number in the hover label of dashboards.
62
+ * Reduced the number of results retrieved from the Google Analytics API per call from 10,000 to 1,000. This is filterable through `yst-ga-filter-api-limit`.
63
+
64
+ * Bugfixes:
65
+ * When toggling checkbox the authentication token input was showing up.
66
+ * Fixed internal links that were being tracked as outbound-article- (with trailing dash).
67
+ * Makes sure re-authentication notice is only shown when authentication has actually failed.
68
+ * Introduces a notice for when authentication isn't the problem but the plugin was somehow unable to fetch data from GA.
69
+
70
+ * i18n:
71
+ * Added translations for `da_DK`, `es_MX`, `fr_FR`, `it_IT`, `nb_NO`, `pl_PL`, `pt_BR`.
72
+ * Updated translations for `en_GB`, `he_IL`, `nl_NL`, `ru_RU`.
73
+
74
  = 5.2.8 =
75
 
76
  Release Date: January 8th, 2015