WP-Matomo (WP-Piwik) - Version 0.9.9.10

Version Description

  • Bugfix: Multisite login issue, see http://wordpress.org/support/topic/0999-multisite-frontend-not-logged-in
  • Bugfix: wpMandrall compatibility, see http://wordpress.org/support/topic/version-0999-conflicts-with-wpmandrill?replies=4
  • Feature: Show page views (actions) in "visitors last 30"
Download this release

Release Info

Developer Braekling
Plugin Icon 128x128 WP-Matomo (WP-Piwik)
Version 0.9.9.10
Comparing to
See all releases

Code changes from version 0.9.9.9 to 0.9.9.10

classes/WP_Piwik.php ADDED
@@ -0,0 +1,1463 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class wp_piwik {
4
+
5
+ private static
6
+ $intRevisionId = 92000,
7
+ $strVersion = '0.9.9.10',
8
+ $blog_id,
9
+ $intDashboardID = 30,
10
+ $strPluginBasename = NULL,
11
+ $bolJustActivated = false,
12
+ $logger,
13
+ $settings;
14
+
15
+ private
16
+ $intStatsPage = NULL,
17
+ $bolNetwork = false,
18
+ $aryAttributes = array(),
19
+ $strResult = '';
20
+
21
+ public function __construct() {
22
+ global $blog_id;
23
+ self::$blog_id = (isset($blog_id)?$blog_id:'n/a');
24
+ $this->openLogger();
25
+ $this->openSettings();
26
+ $this->setup();
27
+ $this->addFilters();
28
+ $this->addActions();
29
+ $this->addShortcodes();
30
+ self::$settings->save();
31
+ }
32
+
33
+ public function __destruct() {
34
+ $this->closeLogger();
35
+ }
36
+
37
+ private function setup() {
38
+ self::$strPluginBasename = plugin_basename(__FILE__);
39
+ register_activation_hook(__FILE__, array($this, 'installPlugin'));
40
+ if ($this->isUpdated())
41
+ $this->upgradePlugin();
42
+ if ($this->isConfigSubmitted())
43
+ $this->applySettings();
44
+ if ($this->isPHPMode())
45
+ self::definePiwikConstants();
46
+ $this->loadLanguage();
47
+ }
48
+
49
+ private function addActions() {
50
+ add_action('admin_menu', array($this, 'buildAdminMenu'));
51
+ add_action('admin_post_save_wp-piwik_stats', array(&$this, 'onStatsPageSaveChanges'));
52
+ add_action('load-post.php', array(&$this, 'postMetaboxes'));
53
+ add_action('load-post-new.php', array(&$this, 'postMetaboxes'));
54
+ if ($this->isNetworkMode())
55
+ add_action('network_admin_menu', array($this, 'buildNetworkAdminMenu'));
56
+ if ($this->isDashboardActive())
57
+ add_action('wp_dashboard_setup', array($this, 'extendWordPressDashboard'));
58
+ if ($this->isToolbarActive()) {
59
+ add_action(is_admin()?'admin_head':'wp_head', array($this, 'loadToolbarRequirements'));
60
+ add_action('admin_bar_menu', array(&$this, 'extendWordPressToolbar'), 1000);
61
+ }
62
+ if ($this->isTrackingActive()) {
63
+ add_action(self::$settings->getGlobalOption('track_codeposition') == 'footer'?'wp_footer':'wp_head', array($this, 'addJavascriptCode'));
64
+ if ($this->isAddNoScriptCode())
65
+ add_action('wp_footer', array($this, 'addNoscriptCode'));
66
+ if ($this->isAdminTrackingActive())
67
+ add_action('admin_head', array($this, 'addAdminHeaderTracking'));
68
+ }
69
+ if (self::$settings->getGlobalOption('add_post_annotations'))
70
+ add_action('transition_post_status', array($this, 'onPostStatusTransition'));
71
+ }
72
+
73
+ private function addFilters() {
74
+ add_filter('plugin_row_meta', array($this, 'setPluginMeta'), 10, 2);
75
+ add_filter('screen_layout_columns', array(&$this, 'onScreenLayoutColumns'), 10, 2);
76
+ if ($this->isTrackingActive()) {
77
+ if ($this->isTrackFeed()) {
78
+ add_filter('the_excerpt_rss', array(&$this, 'addFeedTracking'));
79
+ add_filter('the_content', array(&$this, 'addFeedTracking'));
80
+ }
81
+ if ($this->isAddFeedCampaign())
82
+ add_filter('post_link', array(&$this, 'addFeedCampaign'));
83
+ }
84
+ }
85
+
86
+ private function addShortcodes() {
87
+ if ($this->isAddShortcode())
88
+ add_shortcode('wp-piwik', array(&$this, 'shortcode'));
89
+ }
90
+
91
+ private function loadLanguage() {
92
+ load_plugin_textdomain('wp-piwik', false, dirname(self::$strPluginBasename)."/../languages/");
93
+ }
94
+
95
+ function installPlugin() {
96
+ self::$logger->log('Running WP-Piwik installation');
97
+ add_action('admin_notices', array($this, 'updateMessage'));
98
+ self::$bolJustActivated = true;
99
+ self::$settings->setGlobalOption('revision', self::$intRevisionId);
100
+ self::$settings->setGlobalOption('last_settings_update', time());
101
+ }
102
+
103
+ static function uninstallPlugin() {
104
+ self::$logger->log('Running WP-Piwik uninstallation');
105
+ if (!defined('WP_UNINSTALL_PLUGIN'))
106
+ exit();
107
+ self::$settings->resetSettings(true);
108
+ }
109
+
110
+ function upgradePlugin() {
111
+ self::$logger->log('Upgrade WP-Piwik to '.self::$strVersion);
112
+ add_action('admin_notices', array($this, 'updateMessage'));
113
+ $patches = glob(dirname(__FILE__).DIRECTORY_SEPARATOR.'update'.DIRECTORY_SEPARATOR.'*.php');
114
+ if (is_array($patches)) {
115
+ sort($patches);
116
+ foreach ($patches as $patch) {
117
+ $patchVersion = (int) pathinfo($patch, PATHINFO_FILENAME);
118
+ if ($patchVersion && self::$settings->getGlobalOption('revision') < $patchVersion)
119
+ self::includeFile('update'.DIRECTORY_SEPARATOR.$patchVersion);
120
+ }
121
+ }
122
+ $this->installPlugin();
123
+ }
124
+
125
+ function updateMessage() {
126
+ $text = sprintf(__('%s %s installed.', 'wp-piwik'), self::$settings->getGlobalOption('plugin_display_name'), self::$strVersion);
127
+ $notice = (!self::isConfigured()?
128
+ __('Next you should connect to Piwik','wp-piwik'):
129
+ __('Please validate your configuration','wp-piwik')
130
+ );
131
+ $link = sprintf('<a href="'.getSettingsURL.'?page=%s">%s</a>', self::$strPluginBasename, __('Settings', 'wp-piwik'));
132
+ printf('<div class="updated fade"><p>%s<strong>%s:</strong> %s: %s</p></div>', $text, __('Important', 'wp-piwik'), $notice, $link);
133
+ }
134
+
135
+ function getSettingsURL() {
136
+ return (self::$settings->checkNetworkActivation()?'settings':'options-general').'.php';
137
+ }
138
+
139
+ private function updateTrackingCode() {
140
+ if (!self::$settings->getOption('site_id') || !self::$settings->getOption('tracking_code'))
141
+ $this->addPiwikSite();
142
+ if ($this->isCurrentTrackingCode()) {
143
+ self::$settings->setOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
144
+ self::$settings->save();
145
+ }
146
+ }
147
+
148
+ /* -- </REFACTORED><OLD> -- */
149
+
150
+ function addJavascriptCode() {
151
+ if ($this->isHiddenUser()) {
152
+ self::$logger->log('Do not add tracking code to site header (user should not be tracked) Blog ID: '.self::$blog_id.' Site ID: '.self::$settings->getOption('site_id'));
153
+ return;
154
+ }
155
+ $this->updateTrackingCode();
156
+
157
+ // Change code if 404
158
+ if (is_404() && self::$settings->getGlobalOption('track_404')) {
159
+ self::$logger->log('Apply 404 changes. Blog ID: '.self::$blog_id.' Site ID: '.self::$settings->getOption('site_id'));
160
+ $strTrackingCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['setDocumentTitle', '404/URL = '+String(document.location.pathname+document.location.search).replace(/\//g,'%2f') + '/From = ' + String(document.referrer).replace(/\//g,'%2f')]);\n_paq.push(['trackPageView']);", self::$settings->getOption('tracking_code'));
161
+ }
162
+ // Change code if search result
163
+ elseif (is_search() && self::$settings->getGlobalOption('track_search')) {
164
+ self::$logger->log('Apply search tracking changes. Blog ID: '.self::$blog_id.' Site ID: '.self::$settings->getOption('site_id'));
165
+ $objSearch = new WP_Query("s=" . get_search_query() . '&showposts=-1');
166
+ $intResultCount = $objSearch->post_count;
167
+ $strTrackingCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['trackSiteSearch','".get_search_query()."', false, ".$intResultCount."]);\n_paq.push(['trackPageView']);", self::$settings->getOption('tracking_code'));
168
+ // Use default tracking code
169
+ } else
170
+ $strTrackingCode = self::$settings->getOption('tracking_code');
171
+ // Send tracking code
172
+ self::$logger->log('Add tracking code. Blog ID: '.self::$blog_id.' Site ID: '.self::$settings->getOption('site_id'));
173
+ // Add custom variables if set:
174
+ if (is_single()) {
175
+ $strCustomVars = '';
176
+ for ($i = 1; $i <= 5; $i++) {
177
+ // Get post ID
178
+ $intID = get_the_ID();
179
+ // Get key
180
+ $strMetaKey = get_post_meta($intID, 'wp-piwik_custom_cat'.$i, true);
181
+ // Get value
182
+ $strMetaVal = get_post_meta($intID, 'wp-piwik_custom_val'.$i, true);
183
+ if (!empty($strMetaKey) && !empty($strMetaVal))
184
+ $strCustomVars .= "_paq.push(['setCustomVariable',".$i.", '".$strMetaKey."', '".$strMetaVal."', 'page']);\n";
185
+ }
186
+ if (!empty($strCustomVars)) $strTrackingCode = str_replace("_paq.push(['trackPageView']);", $strCustomVars."_paq.push(['trackPageView']);", $strTrackingCode);
187
+ }
188
+ echo $strTrackingCode;
189
+ $strName = get_bloginfo('name');
190
+ if (self::$settings->getOption('name') != $strName)
191
+ $this->updatePiwikSite();
192
+ }
193
+
194
+ function addNoscriptCode() {
195
+ // Hotfix: Custom capability problem with WP multisite
196
+ if (is_multisite()) {
197
+ foreach (self::$settings->getGlobalOption('capability_stealth') as $strKey => $strVal)
198
+ if ($strVal && current_user_can($strKey))
199
+ return;
200
+ // Don't add tracking code?
201
+ } elseif (current_user_can('wp-piwik_stealth')) return;
202
+ // Send tracking code
203
+ self::$logger->log('Add noscript code. Blog ID: '.self::$blog_id.' Site ID: '.self::$settings->getOption('site_id'));
204
+ echo self::$settings->getOption('noscript_code')."\n";
205
+ }
206
+
207
+ /**
208
+ * Shortcode function
209
+ **/
210
+
211
+ function shortcode($aryAttributes) {
212
+ $this->aryAttributes = shortcode_atts(
213
+ array(
214
+ 'title' => '',
215
+ 'module' => 'overview',
216
+ 'period' => 'day',
217
+ 'date' => 'yesterday',
218
+ 'limit' => 10,
219
+ 'width' => '100%',
220
+ 'height' => '200px',
221
+ 'language' => 'en',
222
+ 'range' => false,
223
+ 'key' => 'sum_daily_nb_uniq_visitors'
224
+ ), $aryAttributes);
225
+ switch ($this->aryAttributes['module']) {
226
+ case 'opt-out':
227
+ $this->strResult = '<iframe frameborder="no" width="'.$this->aryAttributes['width'].'" height="'.$this->aryAttributes['height'].'" src="'.self::$settings->getGlobalOption('piwik_url').'index.php?module=CoreAdminHome&action=optOut&language='.$this->aryAttributes['language'].'"></iframe>';
228
+ break;
229
+ case 'post':
230
+ self::includeFile('shortcodes/post');
231
+ break;
232
+ case 'overview':
233
+ default:
234
+ self::includeFile('shortcodes/overview');
235
+ }
236
+ return $this->strResult;
237
+ }
238
+
239
+ /**
240
+ * Add metaboxes to posts
241
+ */
242
+ function postMetaboxes() {
243
+ if (self::$settings->getGlobalOption('add_customvars_box')) {
244
+ add_action('add_meta_boxes', array(&$this, 'postAddMetaboxes'));
245
+ add_action('save_post', array(&$this, 'postCustomvarsSave'), 10, 2);
246
+ }
247
+ // Show per post stats if enabled
248
+ if (self::$settings->getGlobalOption('perpost_stats')) {
249
+ $this->includeFile('classes/WP_Piwik_MetaBox_PerPost_Stats');
250
+ add_action('add_meta_boxes', array(new WP_Piwik_MetaBox_PerPost_Stats($this->subClassConfig()), 'addMetabox'));
251
+ }
252
+ }
253
+
254
+ /**
255
+ * Create post meta boxes
256
+ */
257
+ function postAddMetaboxes() {
258
+ add_meta_box(
259
+ 'wp-piwik_post_customvars',
260
+ __('Piwik Custom Variables', 'wp-piwik'),
261
+ array(&$this, 'postCustomvars'),
262
+ 'post',
263
+ 'side',
264
+ 'default'
265
+ );
266
+ }
267
+
268
+ /**
269
+ * Display custom variables meta box
270
+ */
271
+ function postCustomvars($objPost, $objBox ) {
272
+ wp_nonce_field(basename( __FILE__ ), 'wp-piwik_post_customvars_nonce'); ?>
273
+ <table>
274
+ <tr><th></th><th><?php _e('Name', 'wp-piwik'); ?></th><th><?php _e('Value', 'wp-piwik'); ?></th></tr>
275
+ <?php for($i = 1; $i <= 5; $i++) { ?>
276
+ <tr>
277
+ <th><label for="wp-piwik_customvar1"><?php echo $i; ?>: </label></th>
278
+ <td><input class="widefat" type="text" name="wp-piwik_custom_cat<?php echo $i; ?>" value="<?php echo esc_attr(get_post_meta($objPost->ID, 'wp-piwik_custom_cat'.$i, true ) ); ?>" size="200" /></td>
279
+ <td><input class="widefat" type="text" name="wp-piwik_custom_val<?php echo $i; ?>" value="<?php echo esc_attr(get_post_meta($objPost->ID, 'wp-piwik_custom_val'.$i, true ) ); ?>" size="200" /></td>
280
+ </tr>
281
+ <?php } ?>
282
+ </table>
283
+ <p><?php _e('Set custom variables for a page view', 'wp-piwik'); ?>. (<a href="http://piwik.org/docs/custom-variables/"><?php _e('More information', 'wp-piwik'); ?></a>.)</p>
284
+ <?php
285
+ }
286
+
287
+ /**
288
+ * Save post custom variables
289
+ */
290
+ function postCustomvarsSave($intID, $objPost) {
291
+ // Verify the nonce before proceeding.
292
+ if (!isset( $_POST['wp-piwik_post_customvars_nonce'] ) || !wp_verify_nonce( $_POST['wp-piwik_post_customvars_nonce'], basename( __FILE__ ) ) )
293
+ return $intID;
294
+ // Get post type object
295
+ $objPostType = get_post_type_object($objPost->post_type);
296
+ // Check if the current user has permission to edit the post.
297
+ if (!current_user_can($objPostType->cap->edit_post, $intID))
298
+ return $intID;
299
+ $aryNames = array('cat', 'val');
300
+ for ($i = 1; $i <= 5; $i++)
301
+ for ($j = 0; $j <= 1; $j++) {
302
+ // Get data
303
+ $strMetaVal = (isset($_POST['wp-piwik_custom_'.$aryNames[$j].$i])?htmlentities($_POST['wp-piwik_custom_'.$aryNames[$j].$i]):'');
304
+ // Create key
305
+ $strMetaKey = 'wp-piwik_custom_'.$aryNames[$j].$i;
306
+ // Get the meta value of the custom field key
307
+ $strCurVal = get_post_meta($intID, $strMetaKey, true);
308
+ // Add meta val:
309
+ if ($strMetaVal && '' == $strCurVal)
310
+ add_post_meta($intID, $strMetaKey, $strMetaVal, true);
311
+ // Update meta val:
312
+ elseif ($strMetaVal && $strMetaVal != $strCurVal)
313
+ update_post_meta($intID, $strMetaKey, $strMetaVal);
314
+ // Delete meta val:
315
+ elseif (''==$strMetaVal && $strCurVal)
316
+ delete_post_meta($intID, $strMetaKey, $strCurVal);
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Add pages to admin menu
322
+ */
323
+ function buildAdminMenu() {
324
+ // Show stats dashboard page if WP-Piwik is configured
325
+ if (self::isConfigured()) {
326
+ // Add dashboard page
327
+ $this->intStatsPage = add_dashboard_page(
328
+ __('Piwik Statistics', 'wp-piwik'),
329
+ self::$settings->getGlobalOption('plugin_display_name'),
330
+ 'wp-piwik_read_stats',
331
+ 'wp-piwik_stats',
332
+ array($this, 'showStats')
333
+ );
334
+ // Add required scripts
335
+ add_action('admin_print_scripts-'.$this->intStatsPage, array($this, 'loadStatsScripts'));
336
+ // Add required styles
337
+ add_action('admin_print_styles-'.$this->intStatsPage, array($this, 'addAdminStyle'));
338
+ // Add required header tags
339
+ add_action('admin_head-'.$this->intStatsPage, array($this, 'addAdminHeaderStats'));
340
+ // Stats page onload callback
341
+ add_action('load-'.$this->intStatsPage, array(&$this, 'onloadStatsPage'));
342
+ }
343
+ if (!self::$settings->checkNetworkActivation()) {
344
+ // Add options page
345
+ $intOptionsPage = add_options_page(
346
+ self::$settings->getGlobalOption('plugin_display_name'),
347
+ self::$settings->getGlobalOption('plugin_display_name'),
348
+ 'activate_plugins',
349
+ __FILE__,
350
+ array($this, 'showSettings')
351
+ );
352
+ // Add required scripts
353
+ add_action('admin_print_scripts-'.$this->intStatsPage, array($this, 'loadSettingsScripts'));
354
+ // Add required header tags
355
+ add_action('admin_head-'.$intOptionsPage, array($this, 'addAdminHeaderSettings'));
356
+ // Add styles required by options page
357
+ add_action('admin_print_styles-'.$intOptionsPage, array($this, 'addAdminStyle'));
358
+ }
359
+ }
360
+
361
+ /**
362
+ * Add pages to network admin menu
363
+ */
364
+ function buildNetworkAdminMenu() {
365
+ // Show stats dashboard page if WP-Piwik is configured
366
+ if (self::isConfigured()) {
367
+ // Add dashboard page
368
+ $this->intStatsPage = add_dashboard_page(
369
+ __('Piwik Statistics', 'wp-piwik'),
370
+ self::$settings->getGlobalOption('plugin_display_name'),
371
+ 'manage_sites',
372
+ 'wp-piwik_stats',
373
+ array($this, 'showStatsNetwork')
374
+ );
375
+ // Add required scripts
376
+ add_action('admin_print_scripts-'.$this->intStatsPage, array($this, 'loadStatsScripts'));
377
+ // Add required styles
378
+ add_action('admin_print_styles-'.$this->intStatsPage, array($this, 'addAdminStyle'));
379
+ // Add required header tags
380
+ add_action('admin_head-'.$this->intStatsPage, array($this, 'addAdminHeaderStats'));
381
+ // Stats page onload callback
382
+ add_action('load-'.$this->intStatsPage, array(&$this, 'onloadStatsPage'));
383
+ }
384
+ $intOptionsPage = add_submenu_page(
385
+ 'settings.php',
386
+ self::$settings->getGlobalOption('plugin_display_name'),
387
+ self::$settings->getGlobalOption('plugin_display_name'),
388
+ 'manage_sites',
389
+ __FILE__,
390
+ array($this, 'showSettings')
391
+ );
392
+
393
+ // Add styles required by options page
394
+ add_action('admin_print_styles-'.$intOptionsPage, array($this, 'addAdminStyle'));
395
+ add_action('admin_head-'.$intOptionsPage, array($this, 'addAdminHeaderSettings'));
396
+ }
397
+
398
+ /**
399
+ * Support two columns
400
+ * seen in Heiko Rabe's metabox demo plugin
401
+ *
402
+ * @see http://tinyurl.com/5r5vnzs
403
+ */
404
+ function onScreenLayoutColumns($aryColumns, $strScreen) {
405
+ if ($strScreen == $this->intStatsPage)
406
+ $aryColumns[$this->intStatsPage] = 3;
407
+ return $aryColumns;
408
+ }
409
+
410
+ /**
411
+ * Add widgets to WordPress dashboard
412
+ */
413
+ function extendWordPressDashboard() {
414
+ // Is user allowed to see stats?
415
+ if (current_user_can('wp-piwik_read_stats')) {
416
+ // TODO: Use bitmask here
417
+ // Add data widget if enabled
418
+ if (self::$settings->getGlobalOption('dashboard_widget'))
419
+ $this->addWordPressDashboardWidget();
420
+ // Add chart widget if enabled
421
+ if (self::$settings->getGlobalOption('dashboard_chart')) {
422
+ // Add required scripts
423
+ add_action('admin_print_scripts-index.php', array($this, 'loadStatsScripts'));
424
+ // Add required styles
425
+ add_action('admin_print_styles-index.php', array($this, 'addAdminStyle'));
426
+ // Add required header tags
427
+ add_action('admin_head-index.php', array($this, 'addAdminHeaderStats'));
428
+ $this->addWordPressDashboardChart();
429
+ }
430
+ // Add SEO widget if enabled
431
+ if (self::$settings->getGlobalOption('dashboard_seo'))
432
+ $this->addWordPressDashboardSEO();
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Add widgets to WordPress Toolbar
438
+ */
439
+ public function extendWordPressToolbar(&$objToolbar) {
440
+ // Is user allowed to see stats?
441
+ if (current_user_can('wp-piwik_read_stats') && is_admin_bar_showing()) {
442
+ $aryUnique = $this->callPiwikAPI('VisitsSummary.getUniqueVisitors','day','last30',null);
443
+ if (!is_array($aryUnique)) $aryUnique = array();
444
+ $strGraph = '<script type="text/javascript">';
445
+ $strGraph .= "var \$jSpark = jQuery.noConflict();\$jSpark(function() {var piwikSparkVals=[".implode(',',$aryUnique)."];\$jSpark('.wp-piwik_dynbar').sparkline(piwikSparkVals, {type: 'bar', barColor: '#ccc', barWidth:2});});";
446
+ $strGraph .= '</script>';
447
+ $strGraph .= '<span class="wp-piwik_dynbar">Loading...</span>';
448
+ $objToolbar->add_menu(array(
449
+ 'id' => 'wp-piwik_stats',
450
+ 'title' => $strGraph,
451
+ 'href' => admin_url().'?page=wp-piwik_stats'
452
+ ));
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Add a data widget to the WordPress dashboard
458
+ */
459
+ function addWordPressDashboardWidget() {
460
+ $aryConfig = array(
461
+ 'params' => array('period' => 'day','date' => self::$settings->getGlobalOption('dashboard_widget'),'limit' => null),
462
+ 'inline' => true,
463
+ );
464
+ $strFile = 'overview';
465
+ add_meta_box(
466
+ 'wp-piwik_stats-dashboard-overview',
467
+ self::$settings->getGlobalOption('plugin_display_name').' - '.__(self::$settings->getGlobalOption('dashboard_widget'), 'wp-piwik'),
468
+ array(&$this, 'createDashboardWidget'),
469
+ 'dashboard',
470
+ 'side',
471
+ 'high',
472
+ array('strFile' => $strFile, 'aryConfig' => $aryConfig)
473
+ );
474
+ }
475
+
476
+ /**
477
+ * Add a visitor chart to the WordPress dashboard
478
+ */
479
+ function addWordPressDashboardChart() {
480
+ $aryConfig = array(
481
+ 'params' => array('period' => 'day','date' => 'last30','limit' => null),
482
+ 'inline' => true,
483
+ );
484
+ $strFile = 'visitors';
485
+ add_meta_box(
486
+ 'wp-piwik_stats-dashboard-chart',
487
+ self::$settings->getGlobalOption('plugin_display_name').' - '.__('Visitors', 'wp-piwik'),
488
+ array(&$this, 'createDashboardWidget'),
489
+ 'dashboard',
490
+ 'side',
491
+ 'high',
492
+ array('strFile' => $strFile, 'aryConfig' => $aryConfig)
493
+ );
494
+ }
495
+
496
+ /**
497
+ * Add a SEO widget to the WordPress dashboard
498
+ */
499
+ function addWordPressDashboardSEO() {
500
+ $aryConfig = array(
501
+ 'params' => array('period' => 'day','date' => 'today','limit' => null),
502
+ 'inline' => true,
503
+ );
504
+ $strFile = 'seo';
505
+ add_meta_box(
506
+ 'wp-piwik_stats-dashboard-seo',
507
+ self::$settings->getGlobalOption('plugin_display_name').' - '.__('SEO', 'wp-piwik'),
508
+ array(&$this, 'createDashboardWidget'),
509
+ 'dashboard',
510
+ 'side',
511
+ 'high',
512
+ array('strFile' => $strFile, 'aryConfig' => $aryConfig)
513
+ );
514
+ }
515
+
516
+ /**
517
+ * Add plugin meta links to plugin details
518
+ *
519
+ * @see http://wpengineer.com/1295/meta-links-for-wordpress-plugins/
520
+ */
521
+ function setPluginMeta($strLinks, $strFile) {
522
+ // Get plugin basename
523
+ $strPlugin = plugin_basename(__FILE__);
524
+ // Add link just to this plugin's details
525
+ if ($strFile == self::$strPluginBasename)
526
+ return array_merge(
527
+ $strLinks,
528
+ array(
529
+ sprintf('<a href="'.(self::$settings->checkNetworkActivation()?'settings':'options-general').'.php?page=%s">%s</a>', self::$strPluginBasename, __('Settings', 'wp-piwik'))
530
+ )
531
+ );
532
+ // Don't affect other plugins details
533
+ return $strLinks;
534
+ }
535
+
536
+ /**
537
+ * Load required scripts to stats page
538
+ */
539
+ function loadStatsScripts() {
540
+ // Load WP-Piwik script
541
+ wp_enqueue_script('wp-piwik', $this->getPluginURL().'js/wp-piwik.js', array(), self::$strVersion, true);
542
+ // Load jqPlot
543
+ wp_enqueue_script('wp-piwik-jqplot',$this->getPluginURL().'js/jqplot/wp-piwik.jqplot.js',array('jquery'));
544
+ }
545
+
546
+ /**
547
+ * Load scripts required by Toolbar graphs
548
+ */
549
+ function loadToolbarRequirements() {
550
+ // Only load if user is allowed to see stats
551
+ if (current_user_can('wp-piwik_read_stats') && is_admin_bar_showing()) {
552
+ // Load Sparklines
553
+ wp_enqueue_script('wp-piwik-sparkline',$this->getPluginURL().'js/sparkline/jquery.sparkline.min.js',array('jquery'),'2.1.1');
554
+ // Load CSS
555
+ wp_enqueue_style('wp-piwik', $this->getPluginURL().'css/wp-piwik-spark.css');
556
+ }
557
+ }
558
+
559
+ /**
560
+ * Load required scripts to settings page
561
+ */
562
+ function loadSettingsScripts() {
563
+ wp_enqueue_script('jquery');
564
+ }
565
+
566
+ /**
567
+ * Load required styles to admin pages
568
+ */
569
+ function addAdminStyle() {
570
+ // Load WP-Piwik styles
571
+ wp_enqueue_style('wp-piwik', $this->getPluginURL().'css/wp-piwik.css',array(),self::$strVersion);
572
+ }
573
+
574
+ /**
575
+ * Add tracking code to admin header
576
+ */
577
+ function addAdminHeaderTracking() {
578
+ $this->site_header();
579
+ }
580
+
581
+ /**
582
+ * Add tracking image to feeds
583
+ **/
584
+ function addFeedTracking($content) {
585
+ global $post;
586
+ if(is_feed()) {
587
+ self::$logger->log('Add tracking image to feed entry.');
588
+ if (!self::$settings->getOption('site_id'))
589
+ self::addPiwikSite();
590
+ $title = the_title(null,null,false);
591
+ $posturl = get_permalink($post->ID);
592
+ $urlref = get_bloginfo('rss2_url');
593
+ $url = self::$settings->getGlobalOption('piwik_url');
594
+ if (substr($url, -10, 10) == '/index.php')
595
+ $url = str_replace('/index.php', '/piwik.php', $url);
596
+ else $url .= 'piwik.php';
597
+ $trackingImage = $url.'?idsite='.self::$settings->getOption('site_id').'&amp;rec=1'.
598
+ '&amp;url='.urlencode($posturl).
599
+ '&amp;action_name='.urlencode($title).
600
+ '&amp;urlref='.urlencode($urlref);
601
+ $content .= '<img src="'.$trackingImage.'" style="border:0;width:0;height:0" width="0" height="0" alt="" />';
602
+ }
603
+ return $content;
604
+ }
605
+
606
+ /**
607
+ * Add tracking image to feeds
608
+ **/
609
+ function addFeedCampaign($permalink) {
610
+ global $post;
611
+ if(is_feed()) {
612
+ self::$logger->log('Add campaign to feed permalink.');
613
+ $sep = (strpos($permalink, '?') === false?'?':'&');
614
+ $permalink .= $sep.'pk_campaign='.urlencode(self::$settings->getGlobalOption('track_feed_campaign')).'&pk_kwd='.urlencode($post->post_name);
615
+ }
616
+ return $permalink;
617
+ }
618
+
619
+ function addPiwikAnnotation($postID) {
620
+ $this->callPiwikAPI('Annotations.add', '', date('Y-m-d'), '', false, false, 'PHP', '', false, 'Published: '.get_post($postID)->post_title.' - URL: '.get_permalink($postID));
621
+ }
622
+
623
+ /**
624
+ * Add required header tags to stats page
625
+ */
626
+ function addAdminHeaderStats() {
627
+ // Load jqPlot IE compatibility script
628
+ echo '<!--[if IE]><script language="javascript" type="text/javascript" src="'.$this->getPluginURL().'js/jqplot/excanvas.min.js"></script><![endif]-->';
629
+ // Load jqPlot styles
630
+ echo '<link rel="stylesheet" href="'.$this->getPluginURL().'js/jqplot/jquery.jqplot.min.css" type="text/css"/>';
631
+ echo '<script type="text/javascript">var $j = jQuery.noConflict();</script>';
632
+ }
633
+
634
+ /**
635
+ * Add required header tags to settings page
636
+ */
637
+ function addAdminHeaderSettings() {
638
+ echo '<script type="text/javascript">var $j = jQuery.noConflict();</script>';
639
+ }
640
+
641
+ /**
642
+ * Get this plugin's URL
643
+ */
644
+ function getPluginURL() {
645
+ // Return plugins URL + /wp-piwik/
646
+ return trailingslashit(plugins_url().'/wp-piwik/');
647
+ }
648
+
649
+ /**
650
+ * Call REST API
651
+ *
652
+ * @param $strURL Remote file URL
653
+ */
654
+ function callREST($strURL) {
655
+ $strPiwikURL = self::$settings->getGlobalOption('piwik_url');
656
+ if (substr($strPiwikURL, -1, 1) != '/') $strPiwikURL .= '/';
657
+ $strURL = $strPiwikURL.'?module=API'.$strURL;
658
+ // Use cURL if available
659
+ if (function_exists('curl_init')) {
660
+ // Init cURL
661
+ $c = curl_init($strURL);
662
+ // Disable SSL peer verification if asked to
663
+ curl_setopt($c, CURLOPT_SSL_VERIFYPEER, !self::$settings->getGlobalOption('disable_ssl_verify'));
664
+ // Set user agent
665
+ curl_setopt($c, CURLOPT_USERAGENT, self::$settings->getGlobalOption('piwik_useragent')=='php'?ini_get('user_agent'):self::$settings->getGlobalOption('piwik_useragent_string'));
666
+ // Configure cURL CURLOPT_RETURNTRANSFER = 1
667
+ curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
668
+ // Configure cURL CURLOPT_HEADER = 0
669
+ curl_setopt($c, CURLOPT_HEADER, 0);
670
+ // Set cURL timeout
671
+ curl_setopt($c, CURLOPT_TIMEOUT, self::$settings->getGlobalOption('connection_timeout'));
672
+ $httpProxyClass = new WP_HTTP_Proxy();
673
+ if ($httpProxyClass->is_enabled() && $httpProxyClass->send_through_proxy($strURL)) {
674
+ curl_setopt($c, CURLOPT_PROXY, $httpProxyClass->host());
675
+ curl_setopt($c, CURLOPT_PROXYPORT, $httpProxyClass->port());
676
+ if ($httpProxyClass->use_authentication())
677
+ curl_setopt($c, CURLOPT_PROXYUSERPWD, $httpProxyClass->username().':'.$httpProxyClass->password());
678
+ }
679
+ // Get result
680
+ $strResult = curl_exec($c);
681
+ // Close connection
682
+ curl_close($c);
683
+ // cURL not available but url fopen allowed
684
+ } elseif (ini_get('allow_url_fopen')) {
685
+ // Set timeout
686
+ $resContext = stream_context_create(array('http'=>array('timeout' => self::$settings->getGlobalOption('connection_timeout'))));
687
+ // Get file using file_get_contents
688
+ $strResult = @file_get_contents($strURL, false, $strContext);
689
+ // Error: Not possible to get remote file
690
+ } else $strResult = serialize(array(
691
+ 'result' => 'error',
692
+ 'message' => 'Remote access to Piwik not possible. Enable allow_url_fopen or CURL.'
693
+ ));
694
+ // Return result
695
+ return $strResult;
696
+ }
697
+
698
+ /**
699
+ * Call PHP API
700
+ *
701
+ * @param $strParams API call params
702
+ */
703
+ function callPHP($strParams) {
704
+ if (!defined('PIWIK_INCLUDE_PATH'))
705
+ return;
706
+ if (PIWIK_INCLUDE_PATH === FALSE)
707
+ return serialize(array('result' => 'error', 'message' => __('Could not resolve','wp-piwik').' &quot;'.htmlentities(self::$settings->getGlobalOption('piwik_path')).'&quot;: '.__('realpath() returns false','wp-piwik').'.'));
708
+ if (file_exists(PIWIK_INCLUDE_PATH . "/index.php"))
709
+ require_once PIWIK_INCLUDE_PATH . "/index.php";
710
+ if (file_exists(PIWIK_INCLUDE_PATH . "/core/API/Request.php"))
711
+ require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php";
712
+ if (class_exists('Piwik\FrontController'))
713
+ Piwik\FrontController::getInstance()->init();
714
+ else serialize(array('result' => 'error', 'message' => __('Class Piwik\FrontController does not exists.','wp-piwik')));
715
+ if (class_exists('Piwik\API\Request'))
716
+ $objRequest = new Piwik\API\Request($strParams);
717
+ else serialize(array('result' => 'error', 'message' => __('Class Piwik\API\Request does not exists.','wp-piwik')));
718
+ return $objRequest->process();
719
+ }
720
+
721
+ /**
722
+ * Get remote file
723
+ *
724
+ * @param String $strURL Remote file URL
725
+ */
726
+ function getRemoteFile($strURL, $blogURL = '') {
727
+ if (self::$settings->getGlobalOption('piwik_mode') == 'php')
728
+ return $this->callPHP($strURL.($blogURL?'&url='.$blogURL:''));
729
+ else
730
+ return $this->callREST($strURL.($blogURL?'&url='.urlencode($blogURL):''));
731
+ }
732
+
733
+ /**
734
+ * Add a new site to Piwik if a new blog was requested,
735
+ * or get its ID by URL
736
+ */
737
+ function addPiwikSite() {
738
+ if (isset($_GET['wpmu_show_stats']) && self::$settings->checkNetworkActivation()) {
739
+ self::$logger->log('Switch blog ID: '.(int) $_GET['wpmu_show_stats']);
740
+ switch_to_blog((int) $_GET['wpmu_show_stats']);
741
+ }
742
+ self::$logger->log('Get the blog\'s site ID by URL: '.get_bloginfo('url'));
743
+ // Check if blog URL already known
744
+ $strURL = '&method=SitesManager.getSitesIdFromSiteUrl';
745
+ $strURL .= '&format=PHP';
746
+ $strURL .= '&token_auth='.self::$settings->getGlobalOption('piwik_token');
747
+ $aryResult = unserialize($this->getRemoteFile($strURL, get_bloginfo('url')));
748
+ if (!empty($aryResult) && isset($aryResult[0]['idsite'])) {
749
+ self::$settings->setOption('site_id', (int) $aryResult[0]['idsite']);
750
+ // Otherwise create new site
751
+ } elseif (self::isConfigured() && !empty($strURL)) {
752
+ self::$logger->log('Blog not known yet - create new site');
753
+ $strName = get_bloginfo('name');
754
+ if (empty($strName)) $strName = get_bloginfo('url');
755
+ self::$settings->setOption('name', $strName);
756
+ $strURL .= '&method=SitesManager.addSite';
757
+ $strURL .= '&siteName='.urlencode($strName).'&urls='.urlencode(get_bloginfo('url'));
758
+ $strURL .= '&format=PHP';
759
+ $strURL .= '&token_auth='.self::$settings->getGlobalOption('piwik_token');
760
+ $strResult = unserialize($this->getRemoteFile($strURL, get_bloginfo('url')));
761
+ if (!empty($strResult)) self::$settings->setOption('site_id', (int) $strResult);
762
+ }
763
+ // Store new data if site created
764
+ if (self::$settings->getOption('site_id')) {
765
+ self::$logger->log('Get the site\'s tracking code');
766
+ self::$settings->setOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
767
+ } else self::$settings->getOption('tracking_code', '');
768
+ self::$settings->save();
769
+ if (isset($_GET['wpmu_show_stats']) && self::$settings->checkNetworkActivation()) {
770
+ self::$logger->log('Back to current blog');
771
+ restore_current_blog();
772
+ }
773
+ return array('js' => self::$settings->getOption('tracking_code'), 'id' => self::$settings->getOption('site_id'));
774
+ }
775
+
776
+ /**
777
+ * Update a site
778
+ */
779
+ function updatePiwikSite() {
780
+ $strBlogURL = get_bloginfo('url');
781
+ // Check if blog URL already known
782
+ $strName = get_bloginfo('name');
783
+ if (empty($strName)) $strName = $strBlogURL;
784
+ self::$settings->setOption('name', $strName);
785
+ $strURL = '&method=SitesManager.updateSite';
786
+ $strURL .= '&idSite='.self::$settings->getOption('site_id');
787
+ $strURL .= '&siteName='.urlencode($strName).'&urls='.urlencode($strBlogURL);
788
+ $strURL .= '&format=PHP';
789
+ $strURL .= '&token_auth='.self::$settings->getGlobalOption('piwik_token');
790
+ $strResult = unserialize($this->getRemoteFile($strURL));
791
+ // Store new data
792
+ self::$settings->getOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
793
+ self::$settings->save();
794
+ }
795
+
796
+ /**
797
+ * Apply configured Tracking Code changes
798
+ */
799
+ function applyJSCodeChanges($strCode) {
800
+ self::$logger->log('Apply tracking code changes.');
801
+ self::$settings->setOption('last_tracking_code_update', time());
802
+ $strCode = html_entity_decode($strCode);
803
+ // Change code if js/index.php should be used
804
+ if (self::$settings->getGlobalOption('track_mode') == 1) {
805
+ $strCode = str_replace('piwik.js', 'js/', $strCode);
806
+ $strCode = str_replace('piwik.php', 'js/', $strCode);
807
+ } elseif (self::$settings->getGlobalOption('track_mode') == 2) {
808
+ $strCode = str_replace('piwik.js', 'piwik.php', $strCode);
809
+ $strURL = str_replace('https://', '://', self::$settings->getGlobalOption('piwik_url'));
810
+ $strURL = str_replace('http://', '://', $strURL);
811
+ $strProxy = str_replace('https://', '://', plugins_url('wp-piwik'));
812
+ $strProxy = str_replace('http://', '://', $strProxy);
813
+ $strProxy .= '/';
814
+ $strCode = str_replace($strURL, $strProxy, $strCode);
815
+ }
816
+ $strCode = str_replace('//";','/"',$strCode);
817
+ if (self::$settings->getGlobalOption('track_cdnurl')||self::$settings->getGlobalOption('track_cdnurlssl')) {
818
+ $strCode = str_replace("var d=doc", "var ucdn=(('https:' == document.location.protocol) ? 'https://".(self::$settings->getGlobalOption('track_cdnurlssl')?self::$settings->getGlobalOption('track_cdnurlssl'):self::$settings->getGlobalOption('track_cdnurl'))."/' : 'http://".(self::$settings->getGlobalOption('track_cdnurl')?self::$settings->getGlobalOption('track_cdnurl'):self::$settings->getGlobalOption('track_cdnurlssl'))."/');\nvar d=doc", $strCode);
819
+ $strCode = str_replace("g.src=u+", "g.src=ucdn+", $strCode);
820
+ }
821
+ // Change code if POST is forced to be used
822
+ if (self::$settings->getGlobalOption('track_post') && self::$settings->getGlobalOption('track_mode') != 2) $strCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['setRequestMethod', 'POST']);\n_paq.push(['trackPageView']);", $strCode);
823
+ // Change code if cookies are disabled
824
+ if (self::$settings->getGlobalOption('track_across')) {
825
+ $referrerParsed = parse_url(get_bloginfo('url'));
826
+ $strCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['setCookieDomain', '*.".$referrerParsed['host']."']);\n_paq.push(['trackPageView']);", $strCode);
827
+ }
828
+ if (self::$settings->getGlobalOption('disable_cookies')) $strCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['disableCookies']);\n_paq.push(['trackPageView']);", $strCode);
829
+ if (self::$settings->getGlobalOption('limit_cookies')) $strCode = str_replace("_paq.push(['trackPageView']);", "_paq.push(['setVisitorCookieTimeout', '".self::$settings->getGlobalOption('limit_cookies_visitor')."']);\n_paq.push(['setSessionCookieTimeout', '".self::$settings->getGlobalOption('limit_cookies_session')."']);\n_paq.push(['trackPageView']);", $strCode);
830
+ // Store <noscript> code
831
+ $aryNoscript = array();
832
+ preg_match('/<noscript>(.*)<\/noscript>/', $strCode, $aryNoscript);
833
+ if (isset($aryNoscript[0])) {
834
+ if (self::$settings->getGlobalOption('track_nojavascript'))
835
+ $aryNoscript[0] = str_replace('?idsite', '?rec=1&idsite', $aryNoscript[0]);
836
+ self::$settings->setOption('noscript_code', $aryNoscript[0]);
837
+ }
838
+ if (self::$settings->getGlobalOption('track_datacfasync'))
839
+ $strCode = str_replace('<script type', '<script data-cfasync="false" type', $strCode);
840
+ // Remove <noscript> code
841
+ $strCode = preg_replace('/<noscript>(.*)<\/noscript>/', '', $strCode);
842
+ // Return code without empty lines
843
+ return preg_replace('/\s+(\r\n|\r|\n)/', '$1', $strCode);
844
+ }
845
+
846
+ /**
847
+ * Create a WordPress dashboard widget
848
+ */
849
+ function createDashboardWidget($objPost, $aryMetabox) {
850
+ // Create description and ID
851
+ $strDesc = $strID = '';
852
+ $aryConfig = $aryMetabox['args']['aryConfig'];
853
+ foreach ($aryConfig['params'] as $strParam)
854
+ if (!empty($strParam)) {
855
+ $strDesc .= $strParam.', ';
856
+ $strID .= '_'.$strParam;
857
+ }
858
+ // Remove dots from filename
859
+ $strFile = str_replace('.', '', $aryMetabox['args']['strFile']);
860
+ // Finalize configuration
861
+ $aryConf = array_merge($aryConfig, array(
862
+ 'id' => $strFile.$strID,
863
+ 'desc' => substr($strDesc, 0, -2)));
864
+ // Include widget file
865
+ if (file_exists(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'dashboard/'.$strFile.'.php'))
866
+ include(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'dashboard/'.$strFile.'.php');
867
+ }
868
+
869
+ /**
870
+ * Call Piwik's API
871
+ */
872
+ function callPiwikAPI($strMethod, $strPeriod='', $strDate='', $intLimit='',$bolExpanded=false, $intId = false, $strFormat = 'PHP', $strPageURL = '', $useCache = true, $strNote = '') {
873
+ // Create unique cache key
874
+ $strKey = 'wp-piwik_'.md5($strMethod.'_'.$strPeriod.'_'.$strDate.'_'.$intLimit.'_'.self::$settings->getGlobalOption('piwik_token').'_'.self::$settings->getGlobalOption('piwik_url').'_'.$intId.'_'.$strPageURL);
875
+ // Call API if data not cached
876
+ if (self::$settings->getGlobalOption('cache') && $useCache) {
877
+ $result = get_transient($strKey);
878
+ self::$logger->log('API method: '.$strMethod.' Fetch call from cache: '.$strKey);
879
+ } else $result = false;
880
+ if ($strMethod == "SitesManager.getSitesWithAtLeastViewAccess" || false === $result) {
881
+ $strToken = self::$settings->getGlobalOption('piwik_token');
882
+ // If multisite stats are shown, maybe the super admin wants to show other blog's stats.
883
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && function_exists('wp_get_current_user') && is_super_admin() && isset($_GET['wpmu_show_stats'])) {
884
+ $aryOptions = get_blog_option((int) $_GET['wpmu_show_stats'], 'wp-piwik_settings' , array());
885
+ if (!empty($aryOptions) && isset($aryOptions['site_id']))
886
+ $intSite = $aryOptions['site_id'];
887
+ else $intSite = self::$settings->getOption('site_id');
888
+ // Otherwise use the current site's id.
889
+ } else {
890
+ if (!self::$settings->getOption('site_id'))
891
+ self::addPiwikSite();
892
+ $intSite = self::$settings->getOption('site_id');
893
+ }
894
+ //die($intSite);
895
+ // Create error message if WP-Piwik isn't configured
896
+ if (!self::isConfigured()) {
897
+ $result = array(
898
+ 'result' => 'error',
899
+ 'message' => 'Piwik URL/path or auth token not set.'
900
+ );
901
+ return $result;
902
+ }
903
+ // Build URL
904
+ $strURL = '&method='.$strMethod;
905
+ $strURL .= '&idSite='.(int)$intSite.'&period='.$strPeriod.'&date='.$strDate;
906
+ $strURL .= '&filter_limit='.$intLimit;
907
+ $strURL .= '&token_auth='.$strToken;
908
+ $strURL .= '&expanded='.$bolExpanded;
909
+ $strURL .= '&format='.$strFormat;
910
+ $strURL .= ($strPageURL?'&pageUrl='.urlencode($strPageURL):'');
911
+ $strURL .= ($strNote?'&note='.urlencode($strNote):'');
912
+ // Fetch data if site exists
913
+ if (!empty($intSite) || $strMethod='SitesManager.getSitesWithAtLeastViewAccess') {
914
+ self::$logger->log('API method: '.$strMethod.' API call: '.$strURL);
915
+ $strResult = (string) $this->getRemoteFile($strURL, get_bloginfo('url'));
916
+ $result = ($strFormat == 'PHP'?unserialize($strResult):$strResult);
917
+ // Apply tracking code changes if configured
918
+ if ($strMethod == 'SitesManager.getJavascriptTag' && !empty($result)) {
919
+ $result = is_string($result)?$this->applyJSCodeChanges($result):'<!-- WP-Piwik ERROR: Tracking code not availbale -->'."\n";
920
+ }
921
+ // Otherwise return error message
922
+ } else $result = array('result' => 'error', 'message' => 'Unknown site/blog.');
923
+ if (
924
+ $strMethod != 'SitesManager.getJavascriptTag' &&
925
+ $strDate != 'today' && $strDate != date('Ymd') && substr($strDate, 0, 4) != 'last' &&
926
+ self::$settings->getGlobalOption('cache') &&
927
+ !(isset($result['result']) && $result['result'] == 'error')&&
928
+ !empty($result)
929
+ ) set_transient($strKey, $result, WEEK_IN_SECONDS);
930
+ }
931
+ return $result;
932
+ }
933
+
934
+ /* TODO: Add post stats
935
+ * function display_post_unique_column($aryCols) {
936
+ * $aryCols['wp-piwik_unique'] = __('Unique');
937
+ * return $aryCols;
938
+ * }
939
+ *
940
+ * function display_post_unique_content($strCol, $intID) {
941
+ * if( $strCol == 'wp-piwik_unique' ) {
942
+ * }
943
+ * }
944
+ */
945
+
946
+ function onloadStatsPage() {
947
+ wp_enqueue_script('common');
948
+ wp_enqueue_script('wp-lists');
949
+ wp_enqueue_script('postbox');
950
+ $strToken = self::$settings->getGlobalOption('piwik_token');
951
+ $strPiwikURL = self::$settings->getGlobalOption('piwik_url');
952
+ $aryDashboard = array();
953
+ // Set default configuration
954
+ $arySortOrder = array(
955
+ 'side' => array(
956
+ 'overview' => array(__('Overview', 'wp-piwik'), 'day', 'yesterday'),
957
+ 'seo' => array(__('SEO', 'wp-piwik'), 'day', 'yesterday'),
958
+ 'pages' => array(__('Pages', 'wp-piwik'), 'day', 'yesterday'),
959
+ 'keywords' => array(__('Keywords', 'wp-piwik'), 'day', 'yesterday', 10),
960
+ 'websites' => array(__('Websites', 'wp-piwik'), 'day', 'yesterday', 10),
961
+ 'plugins' => array(__('Plugins', 'wp-piwik'), 'day', 'yesterday'),
962
+ 'search' => array(__('Site Search Keywords', 'wp-piwik'), 'day', 'yesterday', 10),
963
+ 'noresult' => array(__('Site Search without Results', 'wp-piwik'), 'day', 'yesterday', 10),
964
+ ),
965
+ 'normal' => array(
966
+ 'visitors' => array(__('Visitors', 'wp-piwik'), 'day', 'last30'),
967
+ 'browsers' => array(__('Browser', 'wp-piwik'), 'day', 'yesterday'),
968
+ 'browserdetails' => array(__('Browser Details', 'wp-piwik'), 'day', 'yesterday'),
969
+ 'screens' => array(__('Resolution', 'wp-piwik'), 'day', 'yesterday'),
970
+ 'systems' => array(__('Operating System', 'wp-piwik'), 'day', 'yesterday')
971
+ )
972
+ );
973
+ // Don't show SEO stats if disabled
974
+ if (!self::$settings->getGlobalOption('stats_seo'))
975
+ unset($arySortOrder['side']['seo']);
976
+
977
+ foreach ($arySortOrder as $strCol => $aryWidgets) {
978
+ if (is_array($aryWidgets)) foreach ($aryWidgets as $strFile => $aryParams) {
979
+ $aryDashboard[$strCol][$strFile] = array(
980
+ 'params' => array(
981
+ 'title' => (isset($aryParams[0])?$aryParams[0]:$strFile),
982
+ 'period' => (isset($aryParams[1])?$aryParams[1]:''),
983
+ 'date' => (isset($aryParams[2])?$aryParams[2]:''),
984
+ 'limit' => (isset($aryParams[3])?$aryParams[3]:'')
985
+ )
986
+ );
987
+ if (isset($_GET['date']) && preg_match('/^[0-9]{8}$/', $_GET['date']) && $strFile != 'visitors')
988
+ $aryDashboard[$strCol][$strFile]['params']['date'] = $_GET['date'];
989
+ elseif ($strFile != 'visitors')
990
+ $aryDashboard[$strCol][$strFile]['params']['date'] = self::$settings->getGlobalOption('default_date');
991
+ }
992
+ }
993
+ $intSideBoxCnt = $intContentBox = 0;
994
+ foreach ($aryDashboard['side'] as $strFile => $aryConfig) {
995
+ $intSideBoxCnt++;
996
+ if (preg_match('/(\d{4})(\d{2})(\d{2})/', $aryConfig['params']['date'], $aryResult))
997
+ $strDate = $aryResult[1]."-".$aryResult[2]."-".$aryResult[3];
998
+ else $strDate = $aryConfig['params']['date'];
999
+ add_meta_box(
1000
+ 'wp-piwik_stats-sidebox-'.$intSideBoxCnt,
1001
+ $aryConfig['params']['title'].' '.($aryConfig['params']['title']!='SEO'?__($strDate, 'wp-piwik'):''),
1002
+ array(&$this, 'createDashboardWidget'),
1003
+ $this->intStatsPage,
1004
+ 'side',
1005
+ 'core',
1006
+ array('strFile' => $strFile, 'aryConfig' => $aryConfig)
1007
+ );
1008
+ }
1009
+ foreach ($aryDashboard['normal'] as $strFile => $aryConfig) {
1010
+ if (preg_match('/(\d{4})(\d{2})(\d{2})/', $aryConfig['params']['date'], $aryResult))
1011
+ $strDate = $aryResult[1]."-".$aryResult[2]."-".$aryResult[3];
1012
+ else $strDate = $aryConfig['params']['date'];
1013
+ $intContentBox++;
1014
+ add_meta_box(
1015
+ 'wp-piwik_stats-contentbox-'.$intContentBox,
1016
+ $aryConfig['params']['title'].' '.($aryConfig['params']['title']!='SEO'?__($strDate, 'wp-piwik'):''),
1017
+ array(&$this, 'createDashboardWidget'),
1018
+ $this->intStatsPage,
1019
+ 'normal',
1020
+ 'core',
1021
+ array('strFile' => $strFile, 'aryConfig' => $aryConfig)
1022
+ );
1023
+ }
1024
+ }
1025
+
1026
+ // Open stats page as network admin
1027
+ function showStatsNetwork() {
1028
+ $this->bolNetwork = true;
1029
+ $this->showStats();
1030
+ }
1031
+
1032
+ function showStats() {
1033
+ // Disabled time limit if required
1034
+ if (self::$settings->getGlobalOption('disable_timelimit') && self::$settings->getGlobalOption('disable_timelimit'))
1035
+ set_time_limit(0);
1036
+ //we need the global screen column value to be able to have a sidebar in WordPress 2.8
1037
+ global $screen_layout_columns;
1038
+ if (empty($screen_layout_columns)) $screen_layout_columns = 2;
1039
+ /***************************************************************************/ ?>
1040
+ <div id="wp-piwik-stats-general" class="wrap">
1041
+ <?php screen_icon('options-general'); ?>
1042
+ <h2><?php echo (self::$settings->getGlobalOption('plugin_display_name') == 'WP-Piwik'?'Piwik '.__('Statistics', 'wp-piwik'):self::$settings->getGlobalOption('plugin_display_name')); ?></h2>
1043
+ <?php /************************************************************************/
1044
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && is_super_admin() && $this->bolNetwork) {
1045
+ if (isset($_GET['wpmu_show_stats'])) {
1046
+ switch_to_blog((int) $_GET['wpmu_show_stats']);
1047
+ // TODO OPTIMIZE
1048
+ } else {
1049
+ $this->includeFile('settings/sitebrowser');
1050
+ return;
1051
+ }
1052
+ echo '<p>'.__('Currently shown stats:').' <a href="'.get_bloginfo('url').'">'.(int) $_GET['wpmu_show_stats'].' - '.get_bloginfo('name').'</a>.'.' <a href="?page=wp-piwik_stats">Show site overview</a>.</p>'."\n";
1053
+ echo '</form>'."\n";
1054
+ }
1055
+ /***************************************************************************/ ?>
1056
+ <form action="admin-post.php" method="post">
1057
+ <?php wp_nonce_field('wp-piwik_stats-general'); ?>
1058
+ <?php wp_nonce_field('closedpostboxes', 'closedpostboxesnonce', false ); ?>
1059
+ <?php wp_nonce_field('meta-box-order', 'meta-box-order-nonce', false ); ?>
1060
+ <input type="hidden" name="action" value="save_wp-piwik_stats_general" />
1061
+ <div id="dashboard-widgets" class="metabox-holder columns-<?php echo $screen_layout_columns; ?><?php echo 2 <= $screen_layout_columns?' has-right-sidebar':''; ?>">
1062
+ <div id='postbox-container-1' class='postbox-container'>
1063
+ <?php $meta_boxes = do_meta_boxes($this->intStatsPage, 'normal', null); ?>
1064
+ </div>
1065
+
1066
+ <div id='postbox-container-2' class='postbox-container'>
1067
+ <?php do_meta_boxes($this->intStatsPage, 'side', null); ?>
1068
+ </div>
1069
+
1070
+ <div id='postbox-container-3' class='postbox-container'>
1071
+ <?php do_meta_boxes($this->intStatsPage, 'column3', null); ?>
1072
+ </div>
1073
+
1074
+ </div>
1075
+ </form>
1076
+ </div>
1077
+ <script type="text/javascript">
1078
+ //<![CDATA[
1079
+ jQuery(document).ready( function($) {
1080
+ // close postboxes that should be closed
1081
+ $('.if-js-closed').removeClass('if-js-closed').addClass('closed');
1082
+ // postboxes setup
1083
+ postboxes.add_postbox_toggles('<?php echo $this->intStatsPage; ?>');
1084
+ });
1085
+ //]]>
1086
+ </script>
1087
+ <?php /************************************************************************/
1088
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && is_super_admin()) {
1089
+ restore_current_blog();
1090
+ }
1091
+ }
1092
+
1093
+ /* Stats page changes by POST submit
1094
+ seen in Heiko Rabe's metabox demo plugin
1095
+ http://tinyurl.com/5r5vnzs */
1096
+ function onStatsPageSaveChanges() {
1097
+ //user permission check
1098
+ if ( !current_user_can('manage_options') )
1099
+ wp_die( __('Cheatin&#8217; uh?') );
1100
+ //cross check the given referer
1101
+ check_admin_referer('wp-piwik_stats');
1102
+ //process here your on $_POST validation and / or option saving
1103
+ //lets redirect the post request into get request (you may add additional params at the url, if you need to show save results
1104
+ wp_redirect($_POST['_wp_http_referer']);
1105
+ }
1106
+
1107
+ /**
1108
+ * Add tabs to settings page
1109
+ * See http://wp.smashingmagazine.com/2011/10/20/create-tabs-wordpress-settings-pages/
1110
+ */
1111
+ function showSettingsTabs($bolFull = true, $strCurr = 'homepage') {
1112
+ $aryTabs = ($bolFull?array(
1113
+ 'homepage' => __('Home','wp-piwik'),
1114
+ 'piwik' => __('Piwik Settings','wp-piwik'),
1115
+ 'tracking' => __('Tracking','wp-piwik'),
1116
+ 'views' => __('Statistics','wp-piwik'),
1117
+ 'support' => __('Support','wp-piwik'),
1118
+ 'credits' => __('Credits','wp-piwik')
1119
+ ):array(
1120
+ 'piwik' => __('Piwik Settings','wp-piwik'),
1121
+ 'support' => __('Support','wp-piwik'),
1122
+ 'credits' => __('Credits','wp-piwik')
1123
+ ));
1124
+ if (empty($strCurr)) $strCurr = 'homepage';
1125
+ elseif (!isset($aryTabs[$strCurr]) && $strCurr != 'sitebrowser') $strCurr = 'piwik';
1126
+ echo '<div id="icon-themes" class="icon32"><br></div>';
1127
+ echo '<h2 class="nav-tab-wrapper">';
1128
+ foreach($aryTabs as $strTab => $strName) {
1129
+ $strClass = ($strTab == $strCurr?' nav-tab-active':'');
1130
+ echo '<a class="nav-tab'.$strClass.'" href="?page=wp-piwik/classes/WP_Piwik.php&tab='.$strTab.'">'.$strName.'</a>';
1131
+ }
1132
+ echo '</h2>';
1133
+ return $strCurr;
1134
+ }
1135
+
1136
+ /**
1137
+ * Apply & store new settings
1138
+ */
1139
+ function applySettings() {
1140
+ $strTab = (isset($_GET['tab'])?$_GET['tab']:'homepage');
1141
+ self::$logger->log('Apply changes: '.$strTab);
1142
+ switch ($strTab) {
1143
+ case 'views':
1144
+ self::$settings->setGlobalOption('plugin_display_name', (!empty($_POST['wp-piwik_displayname'])?htmlentities($_POST['wp-piwik_displayname']):'WP-Piwk'));
1145
+ self::$settings->setGlobalOption('dashboard_widget',(isset($_POST['wp-piwik_dbwidget'])?$_POST['wp-piwik_dbwidget']:0));
1146
+ self::$settings->setGlobalOption('dashboard_chart',(isset($_POST['wp-piwik_dbchart'])?$_POST['wp-piwik_dbchart']:false));
1147
+ self::$settings->setGlobalOption('dashboard_seo',(isset($_POST['wp-piwik_dbseo'])?$_POST['wp-piwik_dbseo']:false));
1148
+ self::$settings->setGlobalOption('stats_seo',(isset($_POST['wp-piwik_statsseo'])?$_POST['wp-piwik_statsseo']:false));
1149
+ self::$settings->setGlobalOption('piwik_shortcut', (isset($_POST['wp-piwik_piwiklink'])?$_POST['wp-piwik_piwiklink']:false));
1150
+ self::$settings->setGlobalOption('default_date', (isset($_POST['wp-piwik_default_date'])?$_POST['wp-piwik_default_date']:'yesterday'));
1151
+ self::$settings->setGlobalOption('capability_read_stats', (isset($_POST['wp-piwik_displayto'])?$_POST['wp-piwik_displayto']:array()));
1152
+ self::$settings->setGlobalOption('disable_timelimit', (isset($_POST['wp-piwik_disabletimelimit'])?$_POST['wp-piwik_disabletimelimit']:false));
1153
+ self::$settings->setGlobalOption('toolbar', (isset($_POST['wp-piwik_toolbar'])?$_POST['wp-piwik_toolbar']:false));
1154
+ self::$settings->setGlobalOption('shortcodes', (isset($_POST['wp-piwik_shortcodes'])?$_POST['wp-piwik_shortcodes']:false));
1155
+ self::$settings->setGlobalOption('perpost_stats', (isset($_POST['wp-piwik_perpost'])?$_POST['wp-piwik_perpost']:false));
1156
+ break;
1157
+ case 'tracking':
1158
+ self::$settings->setGlobalOption('add_tracking_code', (isset($_POST['wp-piwik_addjs'])?$_POST['wp-piwik_addjs']:false));
1159
+ self::$settings->setGlobalOption('track_404', (isset($_POST['wp-piwik_404'])?$_POST['wp-piwik_404']:false));
1160
+ self::$settings->setGlobalOption('track_search', (isset($_POST['wp-piwik_search'])?$_POST['wp-piwik_search']:false));
1161
+ self::$settings->setGlobalOption('track_mode', (isset($_POST['wp-piwik_trackingmode'])?(int)$_POST['wp-piwik_trackingmode']:0));
1162
+ self::$settings->setGlobalOption('track_post', (isset($_POST['wp-piwik_reqpost'])?$_POST['wp-piwik_reqpost']:false));
1163
+ self::$settings->setGlobalOption('track_proxy', (isset($_POST['wp-piwik_proxy'])?$_POST['wp-piwik_proxy']:false));
1164
+ self::$settings->setGlobalOption('track_cdnurl', trim(isset($_POST['wp-piwik_cdnurl'])?$_POST['wp-piwik_cdnurl']:''));
1165
+ self::$settings->setGlobalOption('track_cdnurlssl', trim(isset($_POST['wp-piwik_cdnurlssl'])?$_POST['wp-piwik_cdnurlssl']:self::$settings->getGlobalOption('track_cdnurl')));
1166
+ self::$settings->setGlobalOption('track_noscript', (isset($_POST['wp-piwik_noscript'])?$_POST['wp-piwik_noscript']:false));
1167
+ self::$settings->setGlobalOption('track_codeposition', (isset($_POST['wp-piwik_codeposition'])?$_POST['wp-piwik_codeposition']:'footer'));
1168
+ self::$settings->setGlobalOption('track_nojavascript', (isset($_POST['wp-piwik_nojavascript'])?$_POST['wp-piwik_nojavascript']:false));
1169
+ self::$settings->setGlobalOption('track_admin', (isset($_POST['wp-piwik_trackadmin'])?$_POST['wp-piwik_trackadmin']:false));
1170
+ self::$settings->setGlobalOption('track_feed', (isset($_POST['wp-piwik_trackfeed'])?$_POST['wp-piwik_trackfeed']:false));
1171
+ self::$settings->setGlobalOption('track_feed_goal', (isset($_POST['wp-piwik_trackfeed_goal'])&&!empty($_POST['wp-piwik_trackfeed_goal'])?(int)$_POST['wp-piwik_trackfeed_goal']:''));
1172
+ self::$settings->setGlobalOption('track_feed_revenue', (isset($_POST['wp-piwik_trackfeed_revenue'])&&!empty($_POST['wp-piwik_trackfeed_revenue'])?(int)$_POST['wp-piwik_trackfeed_revenue']:''));
1173
+ self::$settings->setGlobalOption('track_feed_campaign', (isset($_POST['wp-piwik_trackfeed_campaign'])?$_POST['wp-piwik_trackfeed_campaign']:'feed'));
1174
+ self::$settings->setGlobalOption('track_feed_addcampaign', (isset($_POST['wp-piwik_trackfeed_addcampaign'])?$_POST['wp-piwik_trackfeed_addcampaign']:false));
1175
+ self::$settings->setGlobalOption('track_datacfasync', (isset($_POST['wp-piwik_datacfasync'])?$_POST['wp-piwik_datacfasync']:false));
1176
+ self::$settings->setGlobalOption('track_across', (isset($_POST['wp-piwik_track_across'])?$_POST['wp-piwik_track_across']:false));
1177
+ self::$settings->setGlobalOption('add_post_annotations', (isset($_POST['wp-piwik_annotations'])?$_POST['wp-piwik_annotations']:false));
1178
+ self::$settings->setGlobalOption('add_customvars_box', (isset($_POST['wp-piwik_customvars'])?$_POST['wp-piwik_customvars']:false));
1179
+ self::$settings->setGlobalOption('capability_stealth', (isset($_POST['wp-piwik_filter'])?$_POST['wp-piwik_filter']:array()));
1180
+ self::$settings->setGlobalOption('disable_cookies', (isset($_POST['wp-piwik_disable_cookies'])?$_POST['wp-piwik_disable_cookies']:false));
1181
+ self::$settings->setGlobalOption('limit_cookies', (isset($_POST['wp-piwik_limit_cookies'])?$_POST['wp-piwik_limit_cookies']:false));
1182
+ self::$settings->setGlobalOption('limit_cookies_visitor', (isset($_POST['wp-piwik_limit_cookies_visitor'])?(int)$_POST['wp-piwik_limit_cookies_visitor']:1209600));
1183
+ self::$settings->setGlobalOption('limit_cookies_session', (isset($_POST['wp-piwik_limit_cookies_session'])?(int)$_POST['wp-piwik_limit_cookies_session']:0));
1184
+ self::$settings->setOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
1185
+ break;
1186
+ case 'piwik':
1187
+ self::$settings->setGlobalOption('piwik_token', (isset($_POST['wp-piwik_token'])?$_POST['wp-piwik_token']:''));
1188
+ self::$settings->setGlobalOption('piwik_url', self::checkURL((isset($_POST['wp-piwik_url'])?$_POST['wp-piwik_url']:'')));
1189
+ self::$settings->setGlobalOption('piwik_path', (isset($_POST['wp-piwik_path']) && !empty($_POST['wp-piwik_path'])?realpath($_POST['wp-piwik_path']):''));
1190
+ self::$settings->setGlobalOption('cache', (isset($_POST['wp-piwik_cache'])?$_POST['wp-piwik_cache']:false));
1191
+ self::$settings->setGlobalOption('piwik_mode', (isset($_POST['wp-piwik_mode'])?$_POST['wp-piwik_mode']:'http'));
1192
+ self::$settings->setGlobalOption('piwik_useragent', (isset($_POST['wp-piwik_useragent'])?$_POST['wp-piwik_useragent']:'php'));
1193
+ self::$settings->setGlobalOption('connection_timeout', (isset($_POST['wp-piwik_timeout'])?(int)$_POST['wp-piwik_timeout']:5));
1194
+ self::$settings->setGlobalOption('piwik_useragent_string', (isset($_POST['wp-piwik_useragent_string'])?$_POST['wp-piwik_useragent_string']:'WP-Piwik'));
1195
+ self::$settings->setGlobalOption('disable_ssl_verify', (isset($_POST['wp-piwik_disable_ssl_verify'])?$_POST['wp-piwik_disable_ssl_verify']:false));
1196
+ if (!self::$settings->checkNetworkActivation()) {
1197
+ self::$settings->setGlobalOption('auto_site_config', (isset($_POST['wp-piwik_auto_site_config'])?$_POST['wp-piwik_auto_site_config']:false));
1198
+ if (!self::$settings->getGlobalOption('auto_site_config'))
1199
+ self::$settings->setOption('site_id', (isset($_POST['wp-piwik_siteid'])?$_POST['wp-piwik_siteid']:self::$settings->getOption('site_id')));
1200
+ } else self::$settings->setGlobalOption('auto_site_config', true);
1201
+ break;
1202
+ }
1203
+ if (self::$settings->getGlobalOption('auto_site_config') && self::isConfigured()) {
1204
+ if (self::$settings->getGlobalOption('piwik_mode') == 'php' && !defined('PIWIK_INCLUDE_PATH'))
1205
+ self::definePiwikConstants();
1206
+ $aryReturn = $this->addPiwikSite();
1207
+ self::$settings->getOption('tracking_code', $aryReturn['js']);
1208
+ self::$settings->getOption('site_id', $aryReturn['id']);
1209
+ }
1210
+ self::$settings->setGlobalOption('last_settings_update', time());
1211
+ }
1212
+
1213
+ /**
1214
+ * Check & prepare URL
1215
+ */
1216
+ static function checkURL($strURL) {
1217
+ if (empty($strURL)) return '';
1218
+ if (substr($strURL, -1, 1) != '/' && substr($strURL, -10, 10) != '/index.php')
1219
+ $strURL .= '/';
1220
+ return $strURL;
1221
+ }
1222
+
1223
+ /**
1224
+ * Show settings page
1225
+ */
1226
+ function showSettings() {
1227
+ // Define globals and get request vars
1228
+ global $pagenow;
1229
+ $strTab = (isset($_GET['tab'])?$_GET['tab']:'homepage');
1230
+ // Show update message if stats saved
1231
+ if (isset($_POST['wp-piwik_settings_submit']) && $_POST['wp-piwik_settings_submit'] == 'Y')
1232
+ echo '<div id="message" class="updated fade"><p>'.__('Changes saved','wp-piwik').'</p></div>';
1233
+ // Show settings page title
1234
+ echo '<div class="wrap"><h2>'.self::$settings->getGlobalOption('plugin_display_name').' '.__('Settings', 'wp-piwik').'</h2>';
1235
+ // Show tabs
1236
+ $strTab = $this->showSettingsTabs(self::isConfigured(), $strTab);
1237
+ if ($strTab != 'sitebrowser') {
1238
+ /***************************************************************************/ ?>
1239
+ <div class="wp-piwik-donate">
1240
+ <p><strong><?php _e('Donate','wp-piwik'); ?></strong></p>
1241
+ <p><?php _e('If you like WP-Piwik, you can support its development by a donation:', 'wp-piwik'); ?></p>
1242
+ <div>
1243
+ <script type="text/javascript">
1244
+ var flattr_url = 'http://www.braekling.de/wp-piwik-wpmu-piwik-wordpress';
1245
+ </script>
1246
+ <script src="http<?php echo (self::isSSL()?'s':''); ?>://api.flattr.com/button/load.js" type="text/javascript"></script>
1247
+ </div>
1248
+ <div>Paypal
1249
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
1250
+ <input type="hidden" name="cmd" value="_s-xclick" />
1251
+ <input type="hidden" name="hosted_button_id" value="6046779" />
1252
+ <input type="image" src="https://www.paypal.com/en_GB/i/btn/btn_donateCC_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." />
1253
+ <img alt="" border="0" src="https://www.paypal.com/de_DE/i/scr/pixel.gif" width="1" height="1" />
1254
+ </form>
1255
+ </div>
1256
+ <div>
1257
+ <a href="http://www.amazon.de/gp/registry/wishlist/111VUJT4HP1RA?reveal=unpurchased&amp;filter=all&amp;sort=priority&amp;layout=standard&amp;x=12&amp;y=14"><?php _e('My Amazon.de wishlist', 'wp-piwik'); ?></a>
1258
+ </div>
1259
+ <div>
1260
+ <?php _e('Please don\'t forget to vote the compatibility at the','wp-piwik'); ?> <a href="http://wordpress.org/extend/plugins/wp-piwik/">WordPress.org Plugin Directory</a>.
1261
+ </div>
1262
+ </div>
1263
+ <?php /***************************************************************************/
1264
+ }
1265
+ echo '<form class="'.($strTab != 'sitebrowser'?'wp-piwik-settings':'').'" method="post" action="'.admin_url(($pagenow == 'settings.php'?'network/':'').$pagenow.'?page=wp-piwik/classes/WP_Piwik.php&tab='.$strTab).'">';
1266
+ echo '<input type="hidden" name="action" value="save_wp-piwik_settings" />';
1267
+ wp_nonce_field('wp-piwik_settings');
1268
+ // Show settings
1269
+ if (($pagenow == 'options-general.php' || $pagenow == 'settings.php') && $_GET['page'] == 'wp-piwik/classes/WP_Piwik.php') {
1270
+ echo '<table class="wp-piwik-form-table form-table">';
1271
+ // Get tab contents
1272
+ $this->includeFile('settings/'.$strTab);
1273
+ // Show submit button
1274
+ if (!in_array($strTab, array('homepage','credits','support','sitebrowser')))
1275
+ echo '<tr><td><p class="submit" style="clear: both;padding:0;margin:0"><input type="submit" name="Submit" class="button-primary" value="'.__('Save settings', 'wp-piwik').'" /><input type="hidden" name="wp-piwik_settings_submit" value="Y" /></p></td></tr>';
1276
+ echo '</table>';
1277
+ }
1278
+ // Close form
1279
+ echo '</form></div>';
1280
+ }
1281
+
1282
+ /**
1283
+ * Check if SSL is used
1284
+ */
1285
+ private static function isSSL() {
1286
+ return (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off');
1287
+ }
1288
+
1289
+ /**
1290
+ * Show an error message extended by a support site link
1291
+ */
1292
+ private static function showErrorMessage($strMessage) {
1293
+ echo '<strong class="wp-piwik-error">'.__('An error occured', 'wp-piwik').':</strong> '.$strMessage.' [<a href="'.(self::$settings->checkNetworkActivation()?'network/settings':'options-general').'.php?page=wp-piwik/classes/WP_Piwik.php&tab=support">'.__('Support','wp-piwik').'</a>]';
1294
+ }
1295
+
1296
+ /**
1297
+ * Read a RSS feed
1298
+ */
1299
+ private static function readRSSFeed($strFeedURL, $intCount = 5) {
1300
+ $aryResult = array();
1301
+ if (function_exists('simplexml_load_file') && !empty($strFeedURL)) {
1302
+ $objXML = @simplexml_load_file($strFeedURL);
1303
+ if (empty($strFeedURL) || !$objXML || !isset($objXML->channel[0]->item))
1304
+ return array(array('title' => 'Can\'t read RSS feed.','url' => $strFeedURL));
1305
+ foreach($objXML->channel[0]->item as $objItem) {
1306
+ if( $intCount-- == 0 ) break;
1307
+ $aryResult[] = array('title' => $objItem->title[0], 'url' => $objItem->link[0]);
1308
+ }
1309
+ }
1310
+ return $aryResult;
1311
+ }
1312
+
1313
+ /**
1314
+ * Execute test script
1315
+ */
1316
+ private static function loadTestscript() {
1317
+ require_once('../debug/testscript.php');
1318
+ }
1319
+
1320
+ /**
1321
+ * Get a blog's piwik ID
1322
+ */
1323
+ public static function getSiteID($intBlogID = null) {
1324
+ $intResult = self::$settings->getOption('site_id');
1325
+ if (self::$settings->checkNetworkActivation() && !empty($intBlogID)) {
1326
+ $aryResult = get_blog_option($intBlogID, 'wp-piwik_settings');
1327
+ $intResult = $aryResult['site_id'];
1328
+ }
1329
+ return (is_int($intResult)?$intResult:'n/a');
1330
+ }
1331
+
1332
+ public static function isConfigured() {
1333
+ return (
1334
+ self::$settings->getGlobalOption('piwik_token')
1335
+ && (
1336
+ (
1337
+ (self::$settings->getGlobalOption('piwik_mode') == 'http') && (self::$settings->getGlobalOption('piwik_url'))
1338
+ ) || (
1339
+ (self::$settings->getGlobalOption('piwik_mode') == 'php') && (self::$settings->getGlobalOption('piwik_path'))
1340
+ )
1341
+ )
1342
+ );
1343
+ }
1344
+
1345
+ private function isUpdated() {
1346
+ return self::$settings->getGlobalOption('revision') && self::$settings->getGlobalOption('revision') < self::$intRevisionId;
1347
+ }
1348
+
1349
+ private function isConfigSubmitted() {
1350
+ return isset($_POST['action']) && $_POST['action'] == 'save_wp-piwik_settings';
1351
+ }
1352
+
1353
+ private function isPHPMode() {
1354
+ return self::$settings->getGlobalOption('piwik_mode') && self::$settings->getGlobalOption('piwik_mode') == 'php';
1355
+ }
1356
+
1357
+ private function isNetworkMode() {
1358
+ return self::$settings->checkNetworkActivation();
1359
+ }
1360
+
1361
+ private function isDashboardActive() {
1362
+ return self::$settings->getGlobalOption('dashboard_widget') || self::$settings->getGlobalOption('dashboard_chart') || self::$settings->getGlobalOption('dashboard_seo');
1363
+ }
1364
+
1365
+ private function isToolbarActive() {
1366
+ return self::$settings->getGlobalOption('toolbar');
1367
+ }
1368
+
1369
+ private function isTrackingActive() {
1370
+ return self::$settings->getGlobalOption('add_tracking_code');
1371
+ }
1372
+
1373
+ private function isAdminTrackingActive() {
1374
+ return self::$settings->getGlobalOption('track_admin');
1375
+ }
1376
+
1377
+ private function isAddNoScriptCode() {
1378
+ return self::$settings->getGlobalOption('track_noscript');
1379
+ }
1380
+
1381
+ private function isTrackFeed() {
1382
+ return self::$settings->getGlobalOption('track_feed');
1383
+ }
1384
+
1385
+ private function isAddFeedCampaign() {
1386
+ return self::$settings->getGlobalOption('track_feed_addcampaign');
1387
+ }
1388
+
1389
+ private function isAddShortcode() {
1390
+ return self::$settings->getGlobalOption('shortcodes');
1391
+ }
1392
+
1393
+ private static function definePiwikConstants() {
1394
+ define('PIWIK_INCLUDE_PATH', self::$settings->getGlobalOption('piwik_path'));
1395
+ define('PIWIK_USER_PATH', self::$settings->getGlobalOption('piwik_path'));
1396
+ define('PIWIK_ENABLE_DISPATCH', false);
1397
+ define('PIWIK_ENABLE_ERROR_HANDLER', false);
1398
+ define('PIWIK_ENABLE_SESSION_START', false);
1399
+ }
1400
+
1401
+ private function openLogger() {
1402
+ switch (WP_PIWIK_ACTIVATE_LOGGER) {
1403
+ case 2:
1404
+ require_once('WP_Piwik_Logger_File.php');
1405
+ self::$logger = new WP_Piwik_Logger_File(__CLASS__);
1406
+ break;
1407
+ default:
1408
+ require_once('WP_Piwik_Logger_Dummy.php');
1409
+ self::$logger = new WP_Piwik_Logger_Dummy(__CLASS__);
1410
+ }
1411
+ }
1412
+
1413
+ private function closeLogger() {
1414
+ self::$logger = null;
1415
+ }
1416
+
1417
+ private function openSettings() {
1418
+ $this->includeFile('classes/WP_Piwik_Settings');
1419
+ self::$settings = new WP_Piwik_Settings(self::$logger);
1420
+ }
1421
+
1422
+ private function subClassConfig() {
1423
+ return array(
1424
+ 'wp_piwik' => $this,
1425
+ 'logger' => self::$logger,
1426
+ 'settings' => self::$settings
1427
+ );
1428
+ }
1429
+
1430
+ private function includeFile($strFile) {
1431
+ self::$logger->log('Include '.$strFile.'.php');
1432
+ if (file_exists(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$strFile.'.php'))
1433
+ include(dirname(__FILE__).DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.$strFile.'.php');
1434
+ }
1435
+
1436
+ private function isHiddenUser() {
1437
+ if (is_multisite())
1438
+ foreach (self::$settings->getGlobalOption('capability_stealth') as $key => $val)
1439
+ if ($val && current_user_can($key)) return true;
1440
+ return current_user_can('wp-piwik_stealth');
1441
+ }
1442
+
1443
+ private function isCurrentTrackingCode() {
1444
+ return (self::$settings->getOption('last_tracking_code_update') < self::$settings->getGlobalOption('last_settings_update'));
1445
+ }
1446
+
1447
+ function site_header() {
1448
+ self::$logger->log('Using deprecated function site_header');
1449
+ $this->addJavascriptCode();
1450
+ }
1451
+
1452
+ function site_footer() {
1453
+ self::$logger->log('Using deprecated function site_footer');
1454
+ $this->addNoscriptCode();
1455
+ }
1456
+
1457
+ private function onPostStatusTransition($newStatus, $oldStatus = 'false', $post = null) {
1458
+ if ($newStatus == 'publish' && $oldStatus != 'publish' ) {
1459
+ add_action('publish_post', array($this, 'addPiwikAnnotation'));
1460
+ }
1461
+ }
1462
+
1463
+ }
classes/WP_Piwik_Settings.php CHANGED
@@ -70,7 +70,7 @@
70
  self::$logger->log('Store default settings');
71
  self::$defaultSettings = array('globalSettings' => $this->globalSettings, 'settings' => $this->settings);
72
  self::$logger->log('Load settings');
73
- $this->globalSettings = (is_plugin_active_for_network('wp-piwik/wp-piwik.php')?
74
  get_site_option('wp-piwik_global-settings', $this->globalSettings):
75
  get_option('wp-piwik_global-settings', $this->globalSettings)
76
  );
@@ -152,4 +152,12 @@
152
  }
153
  $this->save();
154
  }
 
 
 
 
 
 
 
 
155
  }
70
  self::$logger->log('Store default settings');
71
  self::$defaultSettings = array('globalSettings' => $this->globalSettings, 'settings' => $this->settings);
72
  self::$logger->log('Load settings');
73
+ $this->globalSettings = ($this->checkNetworkActivation()?
74
  get_site_option('wp-piwik_global-settings', $this->globalSettings):
75
  get_option('wp-piwik_global-settings', $this->globalSettings)
76
  );
152
  }
153
  $this->save();
154
  }
155
+
156
+ public function checkNetworkActivation() {
157
+ if (!function_exists("is_plugin_active_for_network")) {
158
+ require_once(ABSPATH.'wp-admin/includes/plugin.php');
159
+ wp_cookie_constants();
160
+ }
161
+ return is_plugin_active_for_network('wp-piwik/wp-piwik.php');
162
+ }
163
  }
dashboard/visitors.php CHANGED
@@ -21,7 +21,13 @@
21
  $aryConf['params']['date'],
22
  $aryConf['params']['limit']
23
  );
24
-
 
 
 
 
 
 
25
  if (isset($aryConf['data']['Visitors']['result']) && $aryConf['data']['Visitors']['result'] ='error')
26
  echo '<strong>'.__('Piwik error', 'wp-piwik').':</strong> '.htmlentities($aryConf['data']['Visitors']['message'], ENT_QUOTES, 'utf-8');
27
  else {
@@ -57,6 +63,7 @@
57
  <th class="n"><?php _e('Visits', 'wp-piwik'); ?></th>
58
  <th class="n"><?php _e('Unique', 'wp-piwik'); ?></th>
59
  <th class="n"><?php _e('Bounced', 'wp-piwik'); ?></th>
 
60
  </tr>
61
  </thead>
62
  <tbody style="cursor:pointer;">
@@ -69,6 +76,8 @@
69
  $aryConf['data']['Unique'][$strDate].
70
  '</td><td class="n">'.
71
  $aryConf['data']['Bounced'][$strDate].
 
 
72
  '</td></tr>'."\n";
73
  }
74
  echo '<tr><td class="n" colspan="4"><strong>'.__('Unique TOTAL', 'wp-piwik').'</strong> '.__('Sum', 'wp-piwik').': '.$intUSum.' '.__('Avg', 'wp-piwik').': '.$intAvg.'</td></tr>';
21
  $aryConf['params']['date'],
22
  $aryConf['params']['limit']
23
  );
24
+ $aryConf['data']['Actions'] = $this->callPiwikAPI(
25
+ 'VisitsSummary.getActions',
26
+ $aryConf['params']['period'],
27
+ $aryConf['params']['date'],
28
+ $aryConf['params']['limit']
29
+ );
30
+
31
  if (isset($aryConf['data']['Visitors']['result']) && $aryConf['data']['Visitors']['result'] ='error')
32
  echo '<strong>'.__('Piwik error', 'wp-piwik').':</strong> '.htmlentities($aryConf['data']['Visitors']['message'], ENT_QUOTES, 'utf-8');
33
  else {
63
  <th class="n"><?php _e('Visits', 'wp-piwik'); ?></th>
64
  <th class="n"><?php _e('Unique', 'wp-piwik'); ?></th>
65
  <th class="n"><?php _e('Bounced', 'wp-piwik'); ?></th>
66
+ <th class="n"><?php _e('Page Views', 'wp-piwik'); ?></th>
67
  </tr>
68
  </thead>
69
  <tbody style="cursor:pointer;">
76
  $aryConf['data']['Unique'][$strDate].
77
  '</td><td class="n">'.
78
  $aryConf['data']['Bounced'][$strDate].
79
+ '</td><td class="n">'.
80
+ $aryConf['data']['Actions'][$strDate].
81
  '</td></tr>'."\n";
82
  }
83
  echo '<tr><td class="n" colspan="4"><strong>'.__('Unique TOTAL', 'wp-piwik').'</strong> '.__('Sum', 'wp-piwik').': '.$intUSum.' '.__('Avg', 'wp-piwik').': '.$intAvg.'</td></tr>';
readme.txt CHANGED
@@ -3,7 +3,7 @@
3
  Contributors: Braekling
4
  Requires at least: 3.8
5
  Tested up to: 3.9
6
- Stable tag: 0.9.9.9
7
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6046779
8
  Tags: statistics, stats, analytics, piwik, wpmu
9
 
@@ -13,7 +13,7 @@ This plugin adds a Piwik stats site to your WordPress or WordPress multisite das
13
 
14
  This plugin adds a Piwik stats site to your WordPress dashboard. It's also able to add the Piwik tracking code to your blog using wp_footer.
15
 
16
- **You need a running Piwik (at least 2.0.2) installation** and at least view access to your stats. Also PHP 5 or higher is strictly required.
17
 
18
  Look at the [Piwik website](http://piwik.org/) to get further information about Piwik.
19
 
@@ -49,7 +49,7 @@ See section "Installation".
49
  * Graphs powered by [jqPlot](http://www.jqplot.com/) (GPL 2.0 and MIT) and and [jQuery Sparklines](http://omnipotent.net/jquery.sparkline/) (New BSD License).
50
  * Metabox support inspired by [Heiko Rabe's metabox demo plugin](http://www.code-styling.de/english/how-to-use-wordpress-metaboxes-at-own-plugins).
51
  * Translation credits see plugin settings
52
- * Donations: Marco L., Rolf W., Tobias U., Lars K., Donna F., Kevin D., Ramos S., Thomas M., John C., Andreas G., Ben M., Myra R. I., Carlos U. R.-S., Oleg I., M. N., Daniel K., the Piwik team itself, and all people flattering this.
53
  * All users who send me mails containing criticism, commendation, feature requests and bug reports - you help me to make WP-Piwik much better!
54
 
55
  Thank you all!
@@ -125,6 +125,11 @@ Please update Piwik if not done yet (Piwik 2.0 or higher is recommended)!
125
 
126
  == Changelog ==
127
 
 
 
 
 
 
128
  = 0.9.9.9 =
129
  * Update: PHP API will use namespaces (Piwik 2.x compatibility)
130
  * Update: Piwik URL isn't necessary to use PHP API anymore.
3
  Contributors: Braekling
4
  Requires at least: 3.8
5
  Tested up to: 3.9
6
+ Stable tag: 0.9.9.10
7
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6046779
8
  Tags: statistics, stats, analytics, piwik, wpmu
9
 
13
 
14
  This plugin adds a Piwik stats site to your WordPress dashboard. It's also able to add the Piwik tracking code to your blog using wp_footer.
15
 
16
+ You need a running **Piwik 2.0.2 or higher** installation and at least view access to your stats. Also **PHP 5.3 or higher** is strictly required.
17
 
18
  Look at the [Piwik website](http://piwik.org/) to get further information about Piwik.
19
 
49
  * Graphs powered by [jqPlot](http://www.jqplot.com/) (GPL 2.0 and MIT) and and [jQuery Sparklines](http://omnipotent.net/jquery.sparkline/) (New BSD License).
50
  * Metabox support inspired by [Heiko Rabe's metabox demo plugin](http://www.code-styling.de/english/how-to-use-wordpress-metaboxes-at-own-plugins).
51
  * Translation credits see plugin settings
52
+ * Donations: Marco L., Rolf W., Tobias U., Lars K., Donna F., Kevin D., Ramos S., Thomas M., John C., Andreas G., Ben M., Myra R. I., Carlos U. R.-S., Oleg I., M. N., Daniel K., James L., Jochen K., the Piwik team itself, and all people flattering this.
53
  * All users who send me mails containing criticism, commendation, feature requests and bug reports - you help me to make WP-Piwik much better!
54
 
55
  Thank you all!
125
 
126
  == Changelog ==
127
 
128
+ = 0.9.9.10 =
129
+ * Bugfix: Multisite login issue, see http://wordpress.org/support/topic/0999-multisite-frontend-not-logged-in
130
+ * Bugfix: wpMandrall compatibility, see http://wordpress.org/support/topic/version-0999-conflicts-with-wpmandrill?replies=4
131
+ * Feature: Show page views (actions) in "visitors last 30"
132
+
133
  = 0.9.9.9 =
134
  * Update: PHP API will use namespaces (Piwik 2.x compatibility)
135
  * Update: Piwik URL isn't necessary to use PHP API anymore.
settings/credits.php CHANGED
@@ -1,6 +1,6 @@
1
  <tr>
2
  <td>
3
- <strong><?php _e('Thank you very much for your donation', 'wp-piwik'); ?>:</strong> Marco L., Rolf W., Tobias U., Lars K., Donna F., Kevin D., Ramos S., Thomas M., John C., Andreas G., Ben M., Myra R. I., Carlos U. R.-S., Oleg I., M. N., Daniel K., <?php _e('the Piwik team itself','wp-piwik');?><?php _e(', and all people flattering this','wp-piwik'); ?>!
4
  </td>
5
  </tr>
6
  <tr>
1
  <tr>
2
  <td>
3
+ <strong><?php _e('Thank you very much for your donation', 'wp-piwik'); ?>:</strong> Marco L., Rolf W., Tobias U., Lars K., Donna F., Kevin D., Ramos S., Thomas M., John C., Andreas G., Ben M., Myra R. I., Carlos U. R.-S., Oleg I., M. N., Daniel K., James L., Jochen K., <?php _e('the Piwik team itself','wp-piwik');?><?php _e(', and all people flattering this','wp-piwik'); ?>!
4
  </td>
5
  </tr>
6
  <tr>
wp-piwik.php CHANGED
@@ -6,7 +6,7 @@ Plugin URI: http://wordpress.org/extend/plugins/wp-piwik/
6
 
7
  Description: Adds Piwik stats to your dashboard menu and Piwik code to your wordpress header.
8
 
9
- Version: 0.9.9.9
10
  Author: Andr&eacute; Br&auml;kling
11
  Author URI: http://www.braekling.de
12
 
@@ -33,16 +33,14 @@ if (!function_exists ('add_action')) {
33
  exit();
34
  }
35
 
36
- // Makes sure all required include files are loaded before trying to use it
37
- require_once(ABSPATH.'wp-admin/includes/plugin.php');
38
- require_once(ABSPATH.'wp-includes/pluggable.php');
39
 
40
  if (!class_exists('wp_piwik')) {
41
  class wp_piwik {
42
 
43
  private static
44
- $intRevisionId = 91007,
45
- $strVersion = '0.9.9.9',
46
  $blog_id,
47
  $intDashboardID = 30,
48
  $strPluginBasename = NULL,
@@ -171,7 +169,7 @@ class wp_piwik {
171
  }
172
 
173
  function getSettingsURL() {
174
- return (is_plugin_active_for_network('wp-piwik/wp-piwik.php')?'settings':'options-general').'.php';
175
  }
176
 
177
  private function updateTrackingCode() {
@@ -378,7 +376,7 @@ class wp_piwik {
378
  // Stats page onload callback
379
  add_action('load-'.$this->intStatsPage, array(&$this, 'onloadStatsPage'));
380
  }
381
- if (!is_plugin_active_for_network('wp-piwik/wp-piwik.php')) {
382
  // Add options page
383
  $intOptionsPage = add_options_page(
384
  self::$settings->getGlobalOption('plugin_display_name'),
@@ -476,7 +474,7 @@ class wp_piwik {
476
  */
477
  public function extendWordPressToolbar(&$objToolbar) {
478
  // Is user allowed to see stats?
479
- if (current_user_can('wp-piwik_read_stats')) {
480
  $aryUnique = $this->callPiwikAPI('VisitsSummary.getUniqueVisitors','day','last30',null);
481
  if (!is_array($aryUnique)) $aryUnique = array();
482
  $strGraph = '<script type="text/javascript">';
@@ -564,7 +562,7 @@ class wp_piwik {
564
  return array_merge(
565
  $strLinks,
566
  array(
567
- sprintf('<a href="'.(is_plugin_active_for_network('wp-piwik/wp-piwik.php')?'settings':'options-general').'.php?page=%s">%s</a>', self::$strPluginBasename, __('Settings', 'wp-piwik'))
568
  )
569
  );
570
  // Don't affect other plugins details
@@ -586,7 +584,7 @@ class wp_piwik {
586
  */
587
  function loadToolbarRequirements() {
588
  // Only load if user is allowed to see stats
589
- if (current_user_can('wp-piwik_read_stats')) {
590
  // Load Sparklines
591
  wp_enqueue_script('wp-piwik-sparkline',$this->getPluginURL().'js/sparkline/jquery.sparkline.min.js',array('jquery'),'2.1.1');
592
  // Load CSS
@@ -773,7 +771,7 @@ class wp_piwik {
773
  * or get its ID by URL
774
  */
775
  function addPiwikSite() {
776
- if (isset($_GET['wpmu_show_stats']) && is_plugin_active_for_network('wp-piwik/wp-piwik.php')) {
777
  self::$logger->log('Switch blog ID: '.(int) $_GET['wpmu_show_stats']);
778
  switch_to_blog((int) $_GET['wpmu_show_stats']);
779
  }
@@ -804,7 +802,7 @@ class wp_piwik {
804
  self::$settings->setOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
805
  } else self::$settings->getOption('tracking_code', '');
806
  self::$settings->save();
807
- if (isset($_GET['wpmu_show_stats']) && is_plugin_active_for_network('wp-piwik/wp-piwik.php')) {
808
  self::$logger->log('Back to current blog');
809
  restore_current_blog();
810
  }
@@ -918,7 +916,7 @@ class wp_piwik {
918
  if ($strMethod == "SitesManager.getSitesWithAtLeastViewAccess" || false === $result) {
919
  $strToken = self::$settings->getGlobalOption('piwik_token');
920
  // If multisite stats are shown, maybe the super admin wants to show other blog's stats.
921
- if (is_plugin_active_for_network('wp-piwik/wp-piwik.php') && function_exists('is_super_admin') && function_exists('wp_get_current_user') && is_super_admin() && isset($_GET['wpmu_show_stats'])) {
922
  $aryOptions = get_blog_option((int) $_GET['wpmu_show_stats'], 'wp-piwik_settings' , array());
923
  if (!empty($aryOptions) && isset($aryOptions['site_id']))
924
  $intSite = $aryOptions['site_id'];
@@ -1079,7 +1077,7 @@ class wp_piwik {
1079
  <?php screen_icon('options-general'); ?>
1080
  <h2><?php echo (self::$settings->getGlobalOption('plugin_display_name') == 'WP-Piwik'?'Piwik '.__('Statistics', 'wp-piwik'):self::$settings->getGlobalOption('plugin_display_name')); ?></h2>
1081
  <?php /************************************************************************/
1082
- if (is_plugin_active_for_network('wp-piwik/wp-piwik.php') && function_exists('is_super_admin') && is_super_admin() && $this->bolNetwork) {
1083
  if (isset($_GET['wpmu_show_stats'])) {
1084
  switch_to_blog((int) $_GET['wpmu_show_stats']);
1085
  // TODO OPTIMIZE
@@ -1123,7 +1121,7 @@ class wp_piwik {
1123
  //]]>
1124
  </script>
1125
  <?php /************************************************************************/
1126
- if (is_plugin_active_for_network('wp-piwik/wp-piwik.php') && function_exists('is_super_admin') && is_super_admin()) {
1127
  restore_current_blog();
1128
  }
1129
  }
@@ -1231,7 +1229,7 @@ class wp_piwik {
1231
  self::$settings->setGlobalOption('connection_timeout', (isset($_POST['wp-piwik_timeout'])?(int)$_POST['wp-piwik_timeout']:5));
1232
  self::$settings->setGlobalOption('piwik_useragent_string', (isset($_POST['wp-piwik_useragent_string'])?$_POST['wp-piwik_useragent_string']:'WP-Piwik'));
1233
  self::$settings->setGlobalOption('disable_ssl_verify', (isset($_POST['wp-piwik_disable_ssl_verify'])?$_POST['wp-piwik_disable_ssl_verify']:false));
1234
- if (!is_plugin_active_for_network('wp-piwik/wp-piwik.php')) {
1235
  self::$settings->setGlobalOption('auto_site_config', (isset($_POST['wp-piwik_auto_site_config'])?$_POST['wp-piwik_auto_site_config']:false));
1236
  if (!self::$settings->getGlobalOption('auto_site_config'))
1237
  self::$settings->setOption('site_id', (isset($_POST['wp-piwik_siteid'])?$_POST['wp-piwik_siteid']:self::$settings->getOption('site_id')));
@@ -1328,7 +1326,7 @@ class wp_piwik {
1328
  * Show an error message extended by a support site link
1329
  */
1330
  private static function showErrorMessage($strMessage) {
1331
- echo '<strong class="wp-piwik-error">'.__('An error occured', 'wp-piwik').':</strong> '.$strMessage.' [<a href="'.(is_plugin_active_for_network('wp-piwik/wp-piwik.php')?'network/settings':'options-general').'.php?page=wp-piwik/wp-piwik.php&tab=support">'.__('Support','wp-piwik').'</a>]';
1332
  }
1333
 
1334
  /**
@@ -1360,7 +1358,7 @@ class wp_piwik {
1360
  */
1361
  public static function getSiteID($intBlogID = null) {
1362
  $intResult = self::$settings->getOption('site_id');
1363
- if (is_plugin_active_for_network('wp-piwik/wp-piwik.php') && !empty($intBlogID)) {
1364
  $aryResult = get_blog_option($intBlogID, 'wp-piwik_settings');
1365
  $intResult = $aryResult['site_id'];
1366
  }
@@ -1393,7 +1391,7 @@ class wp_piwik {
1393
  }
1394
 
1395
  private function isNetworkMode() {
1396
- return is_plugin_active_for_network('wp-piwik/wp-piwik.php');
1397
  }
1398
 
1399
  private function isDashboardActive() {
@@ -1401,7 +1399,7 @@ class wp_piwik {
1401
  }
1402
 
1403
  private function isToolbarActive() {
1404
- return is_admin_bar_showing() && self::$settings->getGlobalOption('toolbar');
1405
  }
1406
 
1407
  private function isTrackingActive() {
@@ -1492,7 +1490,7 @@ class wp_piwik {
1492
  $this->addNoscriptCode();
1493
  }
1494
 
1495
- function onPostStatusTransition($newStatus, $oldStatus = 'false', $post = null) {
1496
  if ($newStatus == 'publish' && $oldStatus != 'publish' ) {
1497
  add_action('publish_post', array($this, 'addPiwikAnnotation'));
1498
  }
6
 
7
  Description: Adds Piwik stats to your dashboard menu and Piwik code to your wordpress header.
8
 
9
+ Version: 0.9.9.10
10
  Author: Andr&eacute; Br&auml;kling
11
  Author URI: http://www.braekling.de
12
 
33
  exit();
34
  }
35
 
36
+ //require_once(ABSPATH.'wp-includes/pluggable.php');
 
 
37
 
38
  if (!class_exists('wp_piwik')) {
39
  class wp_piwik {
40
 
41
  private static
42
+ $intRevisionId = 92000,
43
+ $strVersion = '0.9.9.10',
44
  $blog_id,
45
  $intDashboardID = 30,
46
  $strPluginBasename = NULL,
169
  }
170
 
171
  function getSettingsURL() {
172
+ return (self::$settings->checkNetworkActivation()?'settings':'options-general').'.php';
173
  }
174
 
175
  private function updateTrackingCode() {
376
  // Stats page onload callback
377
  add_action('load-'.$this->intStatsPage, array(&$this, 'onloadStatsPage'));
378
  }
379
+ if (!self::$settings->checkNetworkActivation()) {
380
  // Add options page
381
  $intOptionsPage = add_options_page(
382
  self::$settings->getGlobalOption('plugin_display_name'),
474
  */
475
  public function extendWordPressToolbar(&$objToolbar) {
476
  // Is user allowed to see stats?
477
+ if (current_user_can('wp-piwik_read_stats') && is_admin_bar_showing()) {
478
  $aryUnique = $this->callPiwikAPI('VisitsSummary.getUniqueVisitors','day','last30',null);
479
  if (!is_array($aryUnique)) $aryUnique = array();
480
  $strGraph = '<script type="text/javascript">';
562
  return array_merge(
563
  $strLinks,
564
  array(
565
+ sprintf('<a href="'.(self::$settings->checkNetworkActivation()?'settings':'options-general').'.php?page=%s">%s</a>', self::$strPluginBasename, __('Settings', 'wp-piwik'))
566
  )
567
  );
568
  // Don't affect other plugins details
584
  */
585
  function loadToolbarRequirements() {
586
  // Only load if user is allowed to see stats
587
+ if (current_user_can('wp-piwik_read_stats') && is_admin_bar_showing()) {
588
  // Load Sparklines
589
  wp_enqueue_script('wp-piwik-sparkline',$this->getPluginURL().'js/sparkline/jquery.sparkline.min.js',array('jquery'),'2.1.1');
590
  // Load CSS
771
  * or get its ID by URL
772
  */
773
  function addPiwikSite() {
774
+ if (isset($_GET['wpmu_show_stats']) && self::$settings->checkNetworkActivation()) {
775
  self::$logger->log('Switch blog ID: '.(int) $_GET['wpmu_show_stats']);
776
  switch_to_blog((int) $_GET['wpmu_show_stats']);
777
  }
802
  self::$settings->setOption('tracking_code', $this->callPiwikAPI('SitesManager.getJavascriptTag'));
803
  } else self::$settings->getOption('tracking_code', '');
804
  self::$settings->save();
805
+ if (isset($_GET['wpmu_show_stats']) && self::$settings->checkNetworkActivation()) {
806
  self::$logger->log('Back to current blog');
807
  restore_current_blog();
808
  }
916
  if ($strMethod == "SitesManager.getSitesWithAtLeastViewAccess" || false === $result) {
917
  $strToken = self::$settings->getGlobalOption('piwik_token');
918
  // If multisite stats are shown, maybe the super admin wants to show other blog's stats.
919
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && function_exists('wp_get_current_user') && is_super_admin() && isset($_GET['wpmu_show_stats'])) {
920
  $aryOptions = get_blog_option((int) $_GET['wpmu_show_stats'], 'wp-piwik_settings' , array());
921
  if (!empty($aryOptions) && isset($aryOptions['site_id']))
922
  $intSite = $aryOptions['site_id'];
1077
  <?php screen_icon('options-general'); ?>
1078
  <h2><?php echo (self::$settings->getGlobalOption('plugin_display_name') == 'WP-Piwik'?'Piwik '.__('Statistics', 'wp-piwik'):self::$settings->getGlobalOption('plugin_display_name')); ?></h2>
1079
  <?php /************************************************************************/
1080
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && is_super_admin() && $this->bolNetwork) {
1081
  if (isset($_GET['wpmu_show_stats'])) {
1082
  switch_to_blog((int) $_GET['wpmu_show_stats']);
1083
  // TODO OPTIMIZE
1121
  //]]>
1122
  </script>
1123
  <?php /************************************************************************/
1124
+ if (self::$settings->checkNetworkActivation() && function_exists('is_super_admin') && is_super_admin()) {
1125
  restore_current_blog();
1126
  }
1127
  }
1229
  self::$settings->setGlobalOption('connection_timeout', (isset($_POST['wp-piwik_timeout'])?(int)$_POST['wp-piwik_timeout']:5));
1230
  self::$settings->setGlobalOption('piwik_useragent_string', (isset($_POST['wp-piwik_useragent_string'])?$_POST['wp-piwik_useragent_string']:'WP-Piwik'));
1231
  self::$settings->setGlobalOption('disable_ssl_verify', (isset($_POST['wp-piwik_disable_ssl_verify'])?$_POST['wp-piwik_disable_ssl_verify']:false));
1232
+ if (!self::$settings->checkNetworkActivation()) {
1233
  self::$settings->setGlobalOption('auto_site_config', (isset($_POST['wp-piwik_auto_site_config'])?$_POST['wp-piwik_auto_site_config']:false));
1234
  if (!self::$settings->getGlobalOption('auto_site_config'))
1235
  self::$settings->setOption('site_id', (isset($_POST['wp-piwik_siteid'])?$_POST['wp-piwik_siteid']:self::$settings->getOption('site_id')));
1326
  * Show an error message extended by a support site link
1327
  */
1328
  private static function showErrorMessage($strMessage) {
1329
+ echo '<strong class="wp-piwik-error">'.__('An error occured', 'wp-piwik').':</strong> '.$strMessage.' [<a href="'.(self::$settings->checkNetworkActivation()?'network/settings':'options-general').'.php?page=wp-piwik/wp-piwik.php&tab=support">'.__('Support','wp-piwik').'</a>]';
1330
  }
1331
 
1332
  /**
1358
  */
1359
  public static function getSiteID($intBlogID = null) {
1360
  $intResult = self::$settings->getOption('site_id');
1361
+ if (self::$settings->checkNetworkActivation() && !empty($intBlogID)) {
1362
  $aryResult = get_blog_option($intBlogID, 'wp-piwik_settings');
1363
  $intResult = $aryResult['site_id'];
1364
  }
1391
  }
1392
 
1393
  private function isNetworkMode() {
1394
+ return self::$settings->checkNetworkActivation();
1395
  }
1396
 
1397
  private function isDashboardActive() {
1399
  }
1400
 
1401
  private function isToolbarActive() {
1402
+ return self::$settings->getGlobalOption('toolbar');
1403
  }
1404
 
1405
  private function isTrackingActive() {
1490
  $this->addNoscriptCode();
1491
  }
1492
 
1493
+ private function onPostStatusTransition($newStatus, $oldStatus = 'false', $post = null) {
1494
  if ($newStatus == 'publish' && $oldStatus != 'publish' ) {
1495
  add_action('publish_post', array($this, 'addPiwikAnnotation'));
1496
  }