PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.0.5
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.0.5
5.13.0 5.12.1 5.12.0 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 6 years ago Commands 6 years ago Db 6 years ago Ecommerce 6 years ago Report 6 years ago Site 6 years ago TrackingCode 6 years ago User 6 years ago views 6 years ago API.php 6 years ago Access.php 6 years ago AjaxTracker.php 6 years ago Annotations.php 6 years ago Bootstrap.php 6 years ago Capabilities.php 6 years ago Compatibility.php 6 years ago Email.php 6 years ago Installer.php 6 years ago Logger.php 6 years ago OptOut.php 6 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 6 years ago Site.php 6 years ago TrackingCode.php 6 years ago Uninstaller.php 6 years ago Updater.php 6 years ago User.php 6 years ago
Installer.php
313 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\Plugins\Installation\FormDatabaseSetup;
19 use Piwik\SettingsPiwik;
20 use WpMatomo\Site\Sync;
21
22 if ( ! defined( 'ABSPATH' ) ) {
23 exit; // if accessed directly
24 }
25
26 class Installer {
27
28 const OPTION_NAME_INSTALL_DATE = 'matomo-install-date';
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() + 25, 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() + 30, 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() + 35, ScheduledTasks::EVENT_SYNC );
115
116 update_option(self::OPTION_NAME_INSTALL_DATE, time());
117
118 $this->create_website();
119 $this->create_user(); // we sync users as early as possible to make sure things are set up correctly
120 $this->install_tracker();
121
122 try {
123 $this->logger->log( 'Matomo will now init the environment' );
124 $environment = new \Piwik\Application\Environment( null );
125 $environment->init();
126 } catch ( \Exception $e ) {
127 $this->logger->log( 'Ignoring error environment init' );
128 $this->logger->log_exception( 'install_env_init', $e );
129 }
130
131 try {
132 // should load and install plugins
133 $this->logger->log( 'Matomo will now init the front controller and install plugins etc' );
134 \Piwik\FrontController::unsetInstance(); // make sure we're loading the latest instance
135 $controller = \Piwik\FrontController::getInstance();
136 $controller->init();
137 } catch ( \Exception $e ) {
138 $this->logger->log( 'Ignoring error frontcontroller init' );
139 $this->logger->log_exception( 'install_front_init', $e );
140 }
141
142 try {
143 // sync user now again after installing plugins...
144 // before eg the users_language table would not have been available yet
145 $this->create_user();
146 } catch ( \Exception $e ) {
147 $this->logger->log_exception( 'install_create_user', $e );
148 }
149
150 try {
151 // update plugins if there are any
152 $this->update_components();
153 } catch ( \Exception $e ) {
154 $this->logger->log_exception( 'install_update_comp', $e );
155 }
156
157 $this->logger->log( 'Recording version and url' );
158
159 DbHelper::recordInstallVersion();
160
161 if ( ! SettingsPiwik::getPiwikUrl() ) {
162 // especially needed for tests on cli
163 SettingsPiwik::overwritePiwikUrl( plugins_url( 'app', MATOMO_ANALYTICS_FILE ) );
164 }
165
166 $this->logger->log( 'Emptying some caches' );
167
168 \Piwik\Singleton::clearAll();
169 PluginApi::unsetAllInstances();
170 \Piwik\Cache::flushAll();
171
172 $this->logger->log( 'Matomo install finished' );
173 }
174
175 return true;
176 }
177
178 private function install_tracker() {
179 $this->logger->log( 'Matomo is now installing the tracker' );
180 // making sure the tracker will be created in the wp uploads directory
181 $updater = StaticContainer::get( 'Piwik\Plugins\CustomPiwikJs\TrackerUpdater' );
182 $updater->update();
183 }
184
185 private function create_db() {
186 $this->logger->log( 'Matomo will now create the database' );
187
188 try {
189 $db_infos = self::get_db_infos();
190 $config = Config::getInstance();
191 if (isset($config)) {
192 $db_infos = array_merge($config->database, $db_infos);
193 }
194 $config->database = $db_infos;
195
196 DbHelper::checkDatabaseVersion();
197 } catch ( \Exception $e ) {
198 $message = sprintf( 'Database info detection failed with %s in %s:%s.', $e->getMessage(), $e->getFile(), $e->getLine() );
199 throw new \Exception( $message, $e->getCode(), $e );
200 }
201
202 $tables_installed = DbHelper::getTablesInstalled();
203 if ( count( $tables_installed ) > 0 ) {
204 // todo define behaviour... might need to ask user how to proceed... but ideally we add check to
205 // see if all tables are there and if so, reuse them...
206 return $db_infos;
207 }
208 DbHelper::createTables();
209 DbHelper::createAnonymousUser();
210 $this->update_components();
211
212 return $db_infos;
213 }
214
215 private function create_config( $db_info ) {
216 $this->logger->log( 'Matomo is now creating the config' );
217 $domain = home_url();
218 $general = array(
219 'trusted_hosts' => array( $domain ),
220 'salt' => Common::generateUniqId(),
221 );
222 $config = Config::getInstance();
223 $path = $config->getLocalPath();
224 if ( ! is_dir( dirname( $path ) ) ) {
225 wp_mkdir_p( dirname( $path ) );
226 }
227 $db_default = array();
228 $general_default = array();
229 if ( $config->database ) {
230 $db_default = $config->database;
231 }
232 if ( $config->General ) {
233 $general_default = $config->General;
234 }
235 $config->database = array_merge( $db_default, $db_info );
236 $config->General = array_merge( $general_default, $general );
237 $config->forceSave();
238
239 $mode = 0664;
240 @chmod( $config->getLocalPath(), $mode );
241 }
242
243 private function create_website() {
244 $sync = new Sync( $this->settings );
245
246 return $sync->sync_current_site();
247 }
248
249 private function create_user() {
250 $sync = new User\Sync();
251
252 $sync->sync_current_users();
253 }
254
255 /**
256 * @param array $default params
257 * @return array
258 */
259 public static function get_db_infos( $default = array() ) {
260 global $wpdb;
261
262 $socket = '';
263 $host_data = null;
264 $host = null;
265 $port = 3306;
266 if (method_exists($wpdb, 'parse_db_host')) {
267 // WP 4.9+
268 $host_data = $wpdb->parse_db_host( DB_HOST );
269 if ($host_data) {
270 list( $host, $port, $socket, $is_ipv6 ) = $host_data;
271 if (!$port && !$socket) {
272 $port = 3306;
273 }
274 }
275 }
276
277 if (!$host_data || !$host) {
278 // WP 4.8 and older
279 // in case DB credentials change in wordpress, we need to apply these changes here as well on demand
280 $hostParts = explode(':', DB_HOST);
281 $host = $hostParts[0];
282 if (count($hostParts) === 2 && is_numeric($hostParts[1])) {
283 $port = $hostParts[1];
284 } else {
285 $port = 3306;
286 }
287 }
288
289 $database = array(
290 'host' => $host,
291 'port' => $port,
292 'username' => DB_USER,
293 'password' => DB_PASSWORD,
294 'dbname' => DB_NAME,
295 'tables_prefix' => $wpdb->prefix . MATOMO_DATABASE_PREFIX,
296 'adapter' => 'WordPress',
297 );
298 if (!empty($socket)) {
299 $database['unix_socket'] = $socket;
300 }
301 $database = array_merge($default, $database);
302
303 return $database;
304 }
305
306 private function update_components() {
307 $this->logger->log( 'Matomo will now trigger an update' );
308 $updater = new Updater( $this->settings );
309 $updater->update();
310 }
311
312 }
313