PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / classes / WpMatomo / Installer.php
matomo / classes / WpMatomo Last commit date
Admin 5 years ago Commands 6 years ago Db 6 years ago Ecommerce 6 years ago Report 6 years ago Site 5 years ago TrackingCode 5 years ago User 5 years ago views 6 years ago API.php 5 years ago Access.php 6 years ago AjaxTracker.php 5 years ago Annotations.php 6 years ago Bootstrap.php 6 years ago Capabilities.php 6 years ago Compatibility.php 6 years ago Email.php 5 years ago Installer.php 6 years ago Logger.php 5 years ago OptOut.php 5 years ago Paths.php 6 years ago PrivacyBadge.php 6 years ago Referral.php 6 years ago Roles.php 6 years ago ScheduledTasks.php 6 years ago Settings.php 5 years ago Site.php 6 years ago TrackingCode.php 5 years ago Uninstaller.php 6 years ago Updater.php 6 years ago User.php 6 years ago
Installer.php
320 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 * @package matomo
8 */
9
10 namespace WpMatomo;
11
12 use Piwik\Common;
13 use Piwik\Config;
14 use Piwik\Container\StaticContainer;
15 use Piwik\DbHelper;
16 use Piwik\Exception\NotYetInstalledException;
17 use Piwik\Plugin\API as PluginApi;
18 use Piwik\SettingsPiwik;
19 use WpMatomo\Site\Sync;
20
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit; // if accessed directly
23 }
24
25 class Installer {
26
27 const OPTION_NAME_INSTALL_DATE = 'matomo-install-date';
28 const OPTION_NAME_INSTALL_VERSION = 'matomo-install-version';
29
30 /**
31 * @var Settings
32 */
33 private $settings;
34
35 /**
36 * @var Logger
37 */
38 private $logger;
39
40 public function __construct( Settings $settings ) {
41 $this->settings = $settings;
42 $this->logger = new Logger();
43 }
44
45 public function register_hooks() {
46 add_action( 'activate_matomo', array( $this, 'install' ) );
47 }
48
49 public function looks_like_it_is_installed() {
50 $paths = new Paths();
51 $config_file = $paths->get_config_ini_path();
52
53 $config_dir = dirname( $config_file );
54 if ( ! is_dir( $config_dir ) ) {
55 wp_mkdir_p( $config_dir );
56 }
57
58 return file_exists( $config_file );
59 }
60
61 public static function is_intalled() {
62 try {
63 Bootstrap::do_bootstrap();
64
65 return SettingsPiwik::isPiwikInstalled();
66 } catch ( NotYetInstalledException $e ) {
67 // not yet installed.... we will need to install it
68 }
69
70 return false;
71 }
72
73 public function can_be_installed() {
74 $paths = new Paths();
75 $upload_dir = $paths->get_upload_base_dir();
76
77 return is_writable( $upload_dir ) || is_writable( dirname( $upload_dir ) );
78 }
79
80 public function install() {
81 if ( ! $this->can_be_installed() ) {
82 return false;
83 }
84
85 try {
86 // prevent session related errors during install making it more stable
87 if ( ! defined( 'PIWIK_ENABLE_SESSION_START' ) ) {
88 define( 'PIWIK_ENABLE_SESSION_START', false );
89 }
90
91 Bootstrap::do_bootstrap();
92
93 if ( ! SettingsPiwik::isPiwikInstalled() || ! $this->looks_like_it_is_installed() ) {
94 throw new NotYetInstalledException( 'Not yet installed' );
95 }
96
97 return false;
98 } catch ( NotYetInstalledException $e ) {
99 $this->logger->log( 'Matomo is not yet installed... installing now' );
100
101 $db_info = $this->create_db();
102 $this->create_config( $db_info );
103
104 // we're scheduling another update in case there are some dimensions to be updated or anything
105 // it is possible that because the plugins need to be reloaded etc that those updates are not executed right
106 // away but need an actual reload and cache clearance etc
107 wp_schedule_single_event( time() + 30, ScheduledTasks::EVENT_UPDATE );
108
109 // to set up geoip in the background later... don't want this to influence the install
110 wp_schedule_single_event( time() + 35, ScheduledTasks::EVENT_GEOIP );
111
112 // in case something fails with website or user creation
113 // also to set up all the other users
114 wp_schedule_single_event( time() + 45, ScheduledTasks::EVENT_SYNC );
115
116 update_option(self::OPTION_NAME_INSTALL_DATE, time());
117 $plugin_data = get_plugin_data( MATOMO_ANALYTICS_FILE, $markup = false, $translate = false );
118 if ( ! empty( $plugin_data['Version'] )) {
119 update_option( self::OPTION_NAME_INSTALL_VERSION, $plugin_data['Version'] );
120 }
121
122 $this->create_website();
123 $this->create_user(); // we sync users as early as possible to make sure things are set up correctly
124 $this->install_tracker();
125
126 try {
127 $this->logger->log( 'Matomo will now init the environment' );
128 $environment = new \Piwik\Application\Environment( null );
129 $environment->init();
130 } catch ( \Exception $e ) {
131 $this->logger->log( 'Ignoring error environment init' );
132 $this->logger->log_exception( 'install_env_init', $e );
133 }
134
135 try {
136 // should load and install plugins
137 $this->logger->log( 'Matomo will now init the front controller and install plugins etc' );
138 \Piwik\FrontController::unsetInstance(); // make sure we're loading the latest instance
139 $controller = \Piwik\FrontController::getInstance();
140 $controller->init();
141 } catch ( \Exception $e ) {
142 $this->logger->log( 'Ignoring error frontcontroller init' );
143 $this->logger->log_exception( 'install_front_init', $e );
144 }
145
146 try {
147 // sync user now again after installing plugins...
148 // before eg the users_language table would not have been available yet
149 $this->create_user();
150 } catch ( \Exception $e ) {
151 $this->logger->log_exception( 'install_create_user', $e );
152 }
153
154 try {
155 // update plugins if there are any
156 $this->update_components();
157 } catch ( \Exception $e ) {
158 $this->logger->log_exception( 'install_update_comp', $e );
159 }
160
161 $this->logger->log( 'Recording version and url' );
162
163 DbHelper::recordInstallVersion();
164
165 if ( ! SettingsPiwik::getPiwikUrl() ) {
166 // especially needed for tests on cli
167 SettingsPiwik::overwritePiwikUrl( plugins_url( 'app', MATOMO_ANALYTICS_FILE ) );
168 }
169
170 $this->logger->log( 'Emptying some caches' );
171
172 \Piwik\Singleton::clearAll();
173 PluginApi::unsetAllInstances();
174 \Piwik\Cache::flushAll();
175
176 $this->logger->log( 'Matomo install finished' );
177 }
178
179 return true;
180 }
181
182 private function install_tracker() {
183 $this->logger->log( 'Matomo is now installing the tracker' );
184 // making sure the tracker will be created in the wp uploads directory
185 $updater = StaticContainer::get( 'Piwik\Plugins\CustomPiwikJs\TrackerUpdater' );
186 $updater->update();
187 }
188
189 private function create_db() {
190 $this->logger->log( 'Matomo will now create the database' );
191
192 try {
193 $db_infos = self::get_db_infos();
194 $config = Config::getInstance();
195 if (isset($config)) {
196 $db_infos = array_merge($config->database, $db_infos);
197 }
198 $config->database = $db_infos;
199
200 DbHelper::checkDatabaseVersion();
201 } catch ( \Exception $e ) {
202 $message = sprintf( 'Database info detection failed with %s in %s:%s.', $e->getMessage(), $e->getFile(), $e->getLine() );
203 throw new \Exception( $message, $e->getCode(), $e );
204 }
205
206 $tables_installed = DbHelper::getTablesInstalled();
207 if ( count( $tables_installed ) > 0 ) {
208 // todo define behaviour... might need to ask user how to proceed... but ideally we add check to
209 // see if all tables are there and if so, reuse them...
210 return $db_infos;
211 }
212 DbHelper::createTables();
213 DbHelper::createAnonymousUser();
214 $this->update_components();
215
216 return $db_infos;
217 }
218
219 private function create_config( $db_info ) {
220 $this->logger->log( 'Matomo is now creating the config' );
221 $domain = home_url();
222 $general = array(
223 'trusted_hosts' => array( $domain ),
224 'salt' => Common::generateUniqId(),
225 );
226 $config = Config::getInstance();
227 $path = $config->getLocalPath();
228 if ( ! is_dir( dirname( $path ) ) ) {
229 wp_mkdir_p( dirname( $path ) );
230 }
231 $db_default = array();
232 $general_default = array();
233 if ( $config->database ) {
234 $db_default = $config->database;
235 }
236 if ( $config->General ) {
237 $general_default = $config->General;
238 }
239 $config->database = array_merge( $db_default, $db_info );
240 $config->General = array_merge( $general_default, $general );
241 $config->forceSave();
242
243 $mode = 0664;
244 @chmod( $config->getLocalPath(), $mode );
245 }
246
247 private function create_website() {
248 $sync = new Sync( $this->settings );
249
250 return $sync->sync_current_site();
251 }
252
253 private function create_user() {
254 $sync = new User\Sync();
255
256 $sync->sync_current_users();
257 }
258
259 /**
260 * @param array $default params
261 * @return array
262 */
263 public static function get_db_infos( $default = array() ) {
264 global $wpdb;
265
266 $socket = '';
267 $host_data = null;
268 $host = null;
269 $port = 3306;
270 if (method_exists($wpdb, 'parse_db_host')) {
271 // WP 4.9+
272 $host_data = $wpdb->parse_db_host( DB_HOST );
273 if ($host_data) {
274 list( $host, $port, $socket, $is_ipv6 ) = $host_data;
275 if (!$port && !$socket) {
276 $port = 3306;
277 }
278 }
279 }
280
281 if (!$host_data || !$host) {
282 // WP 4.8 and older
283 // in case DB credentials change in wordpress, we need to apply these changes here as well on demand
284 $hostParts = explode(':', DB_HOST);
285 $host = $hostParts[0];
286 if (count($hostParts) === 2 && is_numeric($hostParts[1])) {
287 $port = $hostParts[1];
288 } else {
289 $port = 3306;
290 }
291 }
292
293 $charset = $wpdb->charset ? $wpdb->charset : 'utf8';
294
295 $database = array(
296 'host' => $host,
297 'port' => $port,
298 'username' => DB_USER,
299 'password' => DB_PASSWORD,
300 'dbname' => DB_NAME,
301 'charset' => $charset,
302 'tables_prefix' => $wpdb->prefix . MATOMO_DATABASE_PREFIX,
303 'adapter' => 'WordPress',
304 );
305 if (!empty($socket)) {
306 $database['unix_socket'] = $socket;
307 }
308 $database = array_merge($default, $database);
309
310 return $database;
311 }
312
313 private function update_components() {
314 $this->logger->log( 'Matomo will now trigger an update' );
315 $updater = new Updater( $this->settings );
316 $updater->update();
317 }
318
319 }
320