PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.3
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.3
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 / app / core / Updates / 4.0.0-b1.php
matomo / app / core / Updates Last commit date
3.12.0-b1.php 2 years ago 3.12.0-b7.php 2 years ago 4.0.0-b1.php 2 years ago 4.0.0-b3.php 2 years ago 4.0.0-rc3.php 2 years ago 4.0.0-rc4.php 2 years ago 4.0.1-b1.php 2 years ago 4.0.4-b1.php 2 years ago 4.1.2-b1.php 2 years ago 4.1.2-b2.php 2 years ago 4.10.0-b1.php 2 years ago 4.11.0-b1.php 2 years ago 4.11.0-rc2.php 2 years ago 4.12.0-b1.php 2 years ago 4.12.0-b2.php 2 years ago 4.12.0-b3.php 2 years ago 4.12.0-b4.php 2 years ago 4.3.0-b3.php 2 years ago 4.3.0-b4.php 2 years ago 4.3.0-rc2.php 2 years ago 4.4.0-b1.php 2 years ago 4.5.0-b1.php 2 years ago 4.6.0-b1.php 2 years ago 4.6.0-b4.php 2 years ago 4.6.2-rc2.php 2 years ago 4.7.0-b2.php 2 years ago 4.7.1-b1.php 2 years ago 5.0.0-b1.php 2 years ago 5.0.0-rc2.php 2 years ago 5.0.0-rc5.php 2 years ago
4.0.0-b1.php
234 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 *
9 */
10 namespace Piwik\Updates;
11
12 use Piwik\DataAccess\TableMetadata;
13 use Piwik\Updater\Migration\Custom as CustomMigration;
14 use Piwik\Db;
15 use Piwik\DbHelper;
16 use Piwik\Plugin\Manager;
17 use Piwik\Plugins\CoreAdminHome\Commands\MigrateTokenAuths;
18 use Piwik\Plugins\CoreHome\Columns\Profilable;
19 use Piwik\Plugins\CoreHome\Columns\VisitorSecondsSinceFirst;
20 use Piwik\Plugins\CoreHome\Columns\VisitorSecondsSinceOrder;
21 use Piwik\Plugins\Installation\ServerFilesGenerator;
22 use Piwik\Plugins\PagePerformance\Columns\TimeDomCompletion;
23 use Piwik\Plugins\PagePerformance\Columns\TimeDomProcessing;
24 use Piwik\Plugins\PagePerformance\Columns\TimeNetwork;
25 use Piwik\Plugins\PagePerformance\Columns\TimeOnLoad;
26 use Piwik\Plugins\PagePerformance\Columns\TimeServer;
27 use Piwik\Plugins\PagePerformance\Columns\TimeTransfer;
28 use Piwik\Common;
29 use Piwik\Config;
30 use Piwik\Plugins\UserCountry\LocationProvider;
31 use Piwik\Plugins\VisitorInterest\Columns\VisitorSecondsSinceLast;
32 use Piwik\SettingsPiwik;
33 use Piwik\Updater;
34 use Piwik\Updates as PiwikUpdates;
35 use Piwik\Updater\Migration\Factory as MigrationFactory;
36 /**
37 * Update for version 4.0.0-b1.
38 */
39 class Updates_4_0_0_b1 extends PiwikUpdates
40 {
41 /**
42 * @var MigrationFactory
43 */
44 private $migration;
45 public function __construct(MigrationFactory $factory)
46 {
47 $this->migration = $factory;
48 }
49 public function getMigrations(Updater $updater)
50 {
51 $tableMetadata = new TableMetadata();
52 $columnsToAdd = [];
53 $migrations = [];
54 $domain = Config::getLocalConfigPath() === Config::getDefaultLocalConfigPath() ? '' : Config::getHostname();
55 $domainArg = !empty($domain) ? "--matomo-domain=" . escapeshellarg($domain) . " " : '';
56 $toString = sprintf('./console %score:matomo4-migrate-token-auths', $domainArg);
57 $custom = new CustomMigration(array(MigrateTokenAuths::class, 'migrate'), $toString);
58 $migrations[] = $custom;
59 // invalidations table
60 $migrations[] = $this->migration->db->createTable('archive_invalidations', ['idinvalidation' => 'BIGINT UNSIGNED NOT NULL AUTO_INCREMENT', 'idarchive' => 'INTEGER UNSIGNED NULL', 'name' => 'VARCHAR(255) NOT NULL', 'idsite' => 'INTEGER NOT NULL', 'date1' => 'DATE NOT NULL', 'date2' => 'DATE NOT NULL', 'period' => 'TINYINT UNSIGNED NOT NULL', 'ts_invalidated' => 'DATETIME NOT NULL', 'status' => 'TINYINT(1) UNSIGNED DEFAULT 0', 'report' => 'VARCHAR(255) NULL'], ['idinvalidation']);
61 $migrations[] = $this->migration->db->addIndex('archive_invalidations', ['idsite', 'date1', 'period'], 'index_idsite_dates_period_name');
62 $migrations[] = $this->migration->db->dropColumn('user', 'alias');
63 // prevent possible duplicates when shorting session id
64 $migrations[] = $this->migration->db->sql('DELETE FROM `' . Common::prefixTable('session') . '` WHERE length(id) > 190');
65 $migrations[] = $this->migration->db->changeColumnType('session', 'id', 'VARCHAR(191)');
66 $migrations[] = $this->migration->db->changeColumnType('site_url', 'url', 'VARCHAR(190)');
67 $migrations[] = $this->migration->db->changeColumnType('option', 'option_name', 'VARCHAR(191)');
68 $migrations[] = $this->migration->db->changeColumnType('log_action', 'name', 'VARCHAR(4096)');
69 $migrations[] = $this->migration->db->changeColumnType('log_conversion', 'url', 'VARCHAR(4096)');
70 $migrations[] = $this->migration->db->changeColumn('log_link_visit_action', 'interaction_position', 'pageview_position', 'MEDIUMINT UNSIGNED DEFAULT NULL');
71 $customTrackerPluginActive = false;
72 if (in_array('CustomPiwikJs', Config::getInstance()->Plugins['Plugins'])) {
73 $customTrackerPluginActive = true;
74 }
75 $migrations[] = $this->migration->plugin->activate('BulkTracking');
76 $migrations[] = $this->migration->plugin->deactivate('CustomPiwikJs');
77 $migrations[] = $this->migration->plugin->uninstall('CustomPiwikJs');
78 if ($customTrackerPluginActive) {
79 $migrations[] = $this->migration->plugin->activate('CustomJsTracker');
80 }
81 // Prepare all installed tables for utf8mb4 conversions. e.g. make some indexed fields smaller so they don't exceed the maximum key length
82 $allTables = DbHelper::getTablesInstalled();
83 foreach ($allTables as $table) {
84 if (preg_match('/archive_/', $table) == 1) {
85 $tableNameUnprefixed = Common::unprefixTable($table);
86 $migrations[] = $this->migration->db->changeColumnType($tableNameUnprefixed, 'name', 'VARCHAR(190)');
87 }
88 }
89 // Move the site search fields of log_visit out of custom variables into their own fields
90 $columnsToAdd['log_link_visit_action']['search_cat'] = 'VARCHAR(200) NULL';
91 $columnsToAdd['log_link_visit_action']['search_count'] = 'INTEGER(10) UNSIGNED NULL';
92 // replace days to ... dimensions w/ seconds dimensions
93 foreach (['log_visit', 'log_conversion'] as $table) {
94 $columnsToAdd[$table]['visitor_seconds_since_first'] = VisitorSecondsSinceFirst::COLUMN_TYPE;
95 $columnsToAdd[$table]['visitor_seconds_since_order'] = VisitorSecondsSinceOrder::COLUMN_TYPE;
96 }
97 $columnsToAdd['log_visit']['visitor_seconds_since_last'] = VisitorSecondsSinceLast::COLUMN_TYPE;
98 $columnsToAdd['log_visit']['profilable'] = Profilable::COLUMN_TYPE;
99 $columnsToAdd['log_link_visit_action'][TimeDomCompletion::COLUMN_NAME] = TimeDomCompletion::COLUMN_TYPE;
100 $columnsToAdd['log_link_visit_action'][TimeDomProcessing::COLUMN_NAME] = TimeDomProcessing::COLUMN_TYPE;
101 $columnsToAdd['log_link_visit_action'][TimeNetwork::COLUMN_NAME] = TimeNetwork::COLUMN_TYPE;
102 $columnsToAdd['log_link_visit_action'][TimeOnLoad::COLUMN_NAME] = TimeOnLoad::COLUMN_TYPE;
103 $columnsToAdd['log_link_visit_action'][TimeServer::COLUMN_NAME] = TimeServer::COLUMN_TYPE;
104 $columnsToAdd['log_link_visit_action'][TimeTransfer::COLUMN_NAME] = TimeTransfer::COLUMN_TYPE;
105 $columnsToMaybeAdd = ['revenue', 'revenue_discount', 'revenue_shipping', 'revenue_subtotal', 'revenue_tax'];
106 $columnsLogConversion = $tableMetadata->getColumns(Common::prefixTable('log_conversion'));
107 foreach ($columnsToMaybeAdd as $columnToMaybeAdd) {
108 if (!in_array($columnToMaybeAdd, $columnsLogConversion, true)) {
109 $columnsToAdd['log_conversion'][$columnToMaybeAdd] = 'DOUBLE NULL DEFAULT NULL';
110 }
111 }
112 foreach ($columnsToAdd as $table => $columns) {
113 $migrations[] = $this->migration->db->addColumns($table, $columns);
114 foreach ($columns as $columnName => $columnType) {
115 $optionKey = 'version_' . $table . '.' . $columnName;
116 $optionValue = $columnType;
117 if ($table == 'log_visit' && isset($columnsToAdd['log_conversion'][$columnName])) {
118 $optionValue .= '1';
119 // column is in log_conversion too
120 }
121 $migrations[] = $this->migration->db->sql("INSERT IGNORE INTO `" . Common::prefixTable('option') . "` (option_name, option_value) VALUES ('{$optionKey}', '{$optionValue}')");
122 }
123 }
124 if (Manager::getInstance()->isPluginInstalled('CustomVariables')) {
125 $visitActionTable = Common::prefixTable('log_link_visit_action');
126 $migrations[] = $this->migration->db->sql("UPDATE {$visitActionTable} SET search_cat = if(custom_var_k4 = '_pk_scat', custom_var_v4, search_cat), search_count = if(custom_var_k5 = '_pk_scount', custom_var_v5, search_count) WHERE custom_var_k4 = '_pk_scat' or custom_var_k5 = '_pk_scount'");
127 }
128 if ($this->usesGeoIpLegacyLocationProvider()) {
129 // activate GeoIp2 plugin for users still using GeoIp2 Legacy (others might have it disabled on purpose)
130 $migrations[] = $this->migration->plugin->activate('GeoIp2');
131 }
132 // remove old options
133 $migrations[] = $this->migration->db->sql('DELETE FROM `' . Common::prefixTable('option') . '` WHERE option_name IN ("geoip.updater_period", "geoip.loc_db_url", "geoip.isp_db_url", "geoip.org_db_url")');
134 // init seconds_to_... columns
135 $logVisitColumns = $tableMetadata->getColumns(Common::prefixTable('log_visit'));
136 $hasDaysColumnInVisit = in_array('visitor_days_since_first', $logVisitColumns);
137 if ($hasDaysColumnInVisit) {
138 $migrations[] = $this->migration->db->sql("UPDATE " . Common::prefixTable('log_visit') . " SET visitor_seconds_since_first = visitor_days_since_first * 86400, \n visitor_seconds_since_order = visitor_days_since_order * 86400,\n visitor_seconds_since_last = visitor_days_since_last * 86400");
139 }
140 $logConvColumns = $tableMetadata->getColumns(Common::prefixTable('log_conversion'));
141 $hasDaysColumnInConv = in_array('visitor_days_since_first', $logConvColumns);
142 if ($hasDaysColumnInConv) {
143 $migrations[] = $this->migration->db->sql("UPDATE " . Common::prefixTable('log_conversion') . " SET visitor_seconds_since_first = visitor_days_since_first * 86400, \n visitor_seconds_since_order = visitor_days_since_order * 86400");
144 }
145 // remove old days_to_... columns
146 $migrations[] = $this->migration->db->dropColumns('log_visit', ['config_gears', 'config_director', 'visitor_days_since_first', 'visitor_days_since_order', 'visitor_days_since_last']);
147 $migrations[] = $this->migration->db->dropColumns('log_conversion', ['visitor_days_since_first', 'visitor_days_since_order']);
148 $config = Config::getInstance();
149 if (!empty($config->mail['type']) && $config->mail['type'] === 'Crammd5') {
150 $migrations[] = $this->migration->config->set('mail', 'type', 'Cram-md5');
151 }
152 // keep piwik_ignore for existing installs
153 $migrations[] = $this->migration->config->set('Tracker', 'ignore_visits_cookie_name', 'piwik_ignore');
154 $migrations[] = $this->migration->plugin->activate('PagePerformance');
155 if (!Manager::getInstance()->isPluginActivated('CustomDimensions')) {
156 $migrations[] = $this->migration->plugin->activate('CustomDimensions');
157 }
158 $configTableLimit = Config::getInstance()->getFromLocalConfig('General')['datatable_archiving_maximum_rows_custom_variables'] ?? null;
159 $configSubTableLimit = Config::getInstance()->getFromLocalConfig('General')['datatable_archiving_maximum_rows_subtable_custom_variables'] ?? null;
160 if ($configTableLimit) {
161 $migrations[] = $this->migration->config->set('General', 'datatable_archiving_maximum_rows_custom_dimensions', $configTableLimit);
162 }
163 if ($configSubTableLimit) {
164 $migrations[] = $this->migration->config->set('General', 'datatable_archiving_maximum_rows_subtable_custom_dimensions', $configSubTableLimit);
165 }
166 return $migrations;
167 }
168 public function doUpdate(Updater $updater)
169 {
170 $salt = SettingsPiwik::getSalt();
171 $sessions = Db::fetchAll('SELECT id from ' . Common::prefixTable('session'));
172 foreach ($sessions as $session) {
173 if (!empty($session['id']) && mb_strlen($session['id']) != 128) {
174 $bind = [hash('sha512', $session['id'] . $salt), $session['id']];
175 try {
176 Db::query(sprintf('UPDATE %s SET id = ? WHERE id = ?', Common::prefixTable('session')), $bind);
177 } catch (\Exception $e) {
178 // ignore possible duplicate key errors
179 }
180 }
181 }
182 $updater->executeMigrations(__FILE__, $this->getMigrations($updater));
183 if ($this->usesGeoIpLegacyLocationProvider()) {
184 // switch to default provider if GeoIp Legacy was still in use
185 LocationProvider::setCurrentProvider(LocationProvider\DefaultProvider::ID);
186 }
187 // eg the case when not updating from most recent Matomo 3.X and when not using the UI updater
188 // afterwards the should receive a notification that the plugins are outdated
189 self::ensureCorePluginsThatWereMovedToMarketplaceCanBeUpdated();
190 ServerFilesGenerator::createFilesForSecurity();
191 }
192 public static function ensureCorePluginsThatWereMovedToMarketplaceCanBeUpdated()
193 {
194 $plugins = ['Provider', 'CustomVariables'];
195 $pluginManager = Manager::getInstance();
196 foreach ($plugins as $plugin) {
197 if ($pluginManager->isPluginThirdPartyAndBogus($plugin)) {
198 $pluginDir = Manager::getPluginDirectory($plugin);
199 if (is_dir($pluginDir) && file_exists($pluginDir . '/' . $plugin . '.php') && !file_exists($pluginDir . '/plugin.json') && is_writable($pluginDir)) {
200 file_put_contents($pluginDir . '/plugin.json', '{
201 "name": "' . $plugin . '",
202 "description": "' . $plugin . '",
203 "version": "3.14.1",
204 "theme": false,
205 "require": {
206 "piwik": ">=3.0.0,<4.0.0-b1"
207 },
208 "authors": [
209 {
210 "name": "Matomo",
211 "email": "hello@matomo.org",
212 "homepage": "https:\\/\\/matomo.org"
213 }
214 ],
215 "homepage": "https:\\/\\/matomo.org",
216 "license": "GPL v3+",
217 "keywords": ["' . $plugin . '"]
218 }');
219 // otherwise cached information might be used and it won't be loaded otherwise within same request
220 $pluginObj = $pluginManager->loadPlugin($plugin);
221 $pluginObj->reloadPluginInformation();
222 $pluginManager->unloadPlugin($pluginObj);
223 // prevent any events being posted to it somehow
224 }
225 }
226 }
227 }
228 protected function usesGeoIpLegacyLocationProvider()
229 {
230 $currentProvider = LocationProvider::getCurrentProviderId();
231 return in_array($currentProvider, ['geoip_pecl', 'geoip_php', 'geoip_serverbased']);
232 }
233 }
234