| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\CoreAdminHome\Model; |
|
|
| use Piwik\Common; |
| use Piwik\Container\StaticContainer; |
| use Piwik\DataAccess\TableMetadata; |
| use Piwik\Db; |
| use Piwik\Log\LoggerInterface; |
|
|
| |
| |
| |
| |
| class DuplicateActionRemover |
| { |
| |
| |
| |
| |
| |
| public static $tablesWithIdActionColumns = array( |
| 'log_link_visit_action', |
| 'log_conversion', |
| 'log_conversion_item', |
| ); |
|
|
| |
| |
| |
| |
| |
| private $tableMetadataAccess; |
|
|
| |
| |
| |
| private $logger; |
|
|
| |
| |
| |
| |
| |
| |
| private $idactionColumns = null; |
|
|
| public function __construct(?TableMetadata $tableMetadataAccess = null, ?LoggerInterface $logger = null) |
| { |
| $this->tableMetadataAccess = $tableMetadataAccess ?: new TableMetadata(); |
| $this->logger = $logger ?: StaticContainer::get(LoggerInterface::class); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getDuplicateIdActions() |
| { |
| $sql = "SELECT name, COUNT(*) AS count, GROUP_CONCAT(idaction ORDER BY idaction ASC SEPARATOR ',') as idactions |
| FROM " . Common::prefixTable('log_action') . " |
| GROUP BY name, hash, type HAVING count > 1"; |
|
|
| $result = array(); |
| foreach (Db::fetchAll($sql) as $row) { |
| $dupeInfo = array('name' => $row['name']); |
|
|
| $idActions = explode(",", $row['idactions']); |
| $dupeInfo['idaction'] = array_shift($idActions); |
| $dupeInfo['duplicateIdActions'] = $idActions; |
|
|
| $result[] = $dupeInfo; |
| } |
| return $result; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function fixDuplicateActionsInTable($table, $realIdAction, $duplicateIdActions) |
| { |
| $idactionColumns = $this->getIdActionTableColumnsFromMetadata(); |
| $idactionColumns = array_values($idactionColumns[$table]); |
| $table = Common::prefixTable($table); |
|
|
| $inFromIdsExpression = $this->getInFromIdsExpression($duplicateIdActions); |
| $setExpression = "%1\$s = IF(($inFromIdsExpression), $realIdAction, %1\$s)"; |
|
|
| $sql = "UPDATE $table SET\n"; |
| foreach ($idactionColumns as $index => $column) { |
| if ($index != 0) { |
| $sql .= ",\n"; |
| } |
| $sql .= sprintf($setExpression, $column); |
| } |
| $sql .= $this->getWhereToGetRowsUsingDuplicateActions($idactionColumns, $duplicateIdActions); |
|
|
| Db::query($sql); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getSitesAndDatesOfRowsUsingDuplicates($table, $duplicateIdActions) |
| { |
| $idactionColumns = $this->getIdActionTableColumnsFromMetadata(); |
| $idactionColumns = array_values($idactionColumns[$table]); |
| $table = Common::prefixTable($table); |
|
|
| $sql = "SELECT idsite, DATE(server_time) as server_time FROM `$table` "; |
| $sql .= $this->getWhereToGetRowsUsingDuplicateActions($idactionColumns, $duplicateIdActions); |
| return Db::fetchAll($sql); |
| } |
|
|
| private function getIdActionTableColumnsFromMetadata() |
| { |
| if ($this->idactionColumns === null) { |
| $this->idactionColumns = array(); |
| foreach (self::$tablesWithIdActionColumns as $table) { |
| $columns = $this->tableMetadataAccess->getIdActionColumnNames(Common::prefixTable($table)); |
|
|
| $this->logger->debug("Found following idactions in {table}: {columns}", array( |
| 'table' => $table, |
| 'columns' => implode(',', $columns), |
| )); |
|
|
| $this->idactionColumns[$table] = $columns; |
| } |
| } |
| return $this->idactionColumns; |
| } |
|
|
| private function getWhereToGetRowsUsingDuplicateActions($idactionColumns, $fromIdActions) |
| { |
| $sql = "WHERE "; |
| foreach ($idactionColumns as $index => $column) { |
| if ($index != 0) { |
| $sql .= "OR "; |
| } |
|
|
| $sql .= sprintf($this->getInFromIdsExpression($fromIdActions), $column) . " "; |
| } |
| return $sql; |
| } |
|
|
| private function getInFromIdsExpression($fromIdActions) |
| { |
| return "%1\$s IN (" . implode(',', $fromIdActions) . ")"; |
| } |
| } |
|
|