processNewSegmentsFrom = StaticContainer::get('ini.General.process_new_segments_from'); $this->beginningOfTimeLastNInYears = $beginningOfTimeLastNInYears; $this->segmentEditorModel = $segmentEditorModel ?: new Model(); $this->segmentListCache = $segmentListCache ?: new Transient(); $this->now = $now ?: Date::factory('now'); $this->logger = $logger ?: StaticContainer::get('Psr\Log\LoggerInterface'); $this->forceArchiveAllSegments = self::getShouldForceArchiveAllSegments(); } public function findSegmentForHash($hash, $idSite) { foreach ($this->getAllSegments() as $segment) { if (!$this->isAutoArchivingEnabledFor($segment) || !self::isSegmentForSite($segment, $idSite) ) { continue; } try { $segmentObj = new Segment($segment['definition'], [$idSite]); } catch (\Exception $ex) { $this->logger->debug("Could not process segment {$segment['definition']} for site {$idSite}. Segment should not exist for the site, but does."); continue; } if ($segmentObj->getHash() == $hash) { return $segment; } } return null; } public function getReArchiveSegmentStartDate($segmentInfo) { /** * @var Date $segmentCreatedTime * @var Date $segmentLastEditedTime */ list($segmentCreatedTime, $segmentLastEditedTime) = $this->getCreatedTimeOfSegment($segmentInfo); if ($this->processNewSegmentsFrom == SegmentArchiving::CREATION_TIME) { if (empty($segmentCreatedTime)) { return null; } $this->logger->debug("process_new_segments_from set to segment_creation_time, oldest date to process is {time}", array('time' => $segmentCreatedTime)); return $segmentCreatedTime; } else if ($this->processNewSegmentsFrom == SegmentArchiving::LAST_EDIT_TIME) { if (empty($segmentLastEditedTime)) { return null; } $this->logger->debug("process_new_segments_from set to segment_last_edit_time, segment last edit time is {time}", array('time' => $segmentLastEditedTime)); return $segmentLastEditedTime; } else if (preg_match("/^editLast([0-9]+)$/", $this->processNewSegmentsFrom, $matches)) { if (empty($segmentLastEditedTime)) { return null; } $lastN = $matches[1]; list($lastDate, $lastPeriod) = Range::getDateXPeriodsAgo($lastN, $segmentLastEditedTime, 'day'); $result = Date::factory($lastDate); $this->logger->debug("process_new_segments_from set to editLast{N}, oldest date to process is {time}", array('N' => $lastN, 'time' => $result)); return $result; } else if (preg_match("/^last([0-9]+)$/", $this->processNewSegmentsFrom, $matches)) { if (empty($segmentCreatedTime)) { return null; } $lastN = $matches[1]; list($lastDate, $lastPeriod) = Range::getDateXPeriodsAgo($lastN, $segmentCreatedTime, 'day'); $result = Date::factory($lastDate); $this->logger->debug("process_new_segments_from set to last{N}, oldest date to process is {time}", array('N' => $lastN, 'time' => $result)); return $result; } else { $this->logger->debug("process_new_segments_from set to beginning_of_time or cannot recognize value"); $result = Date::factory('today')->subYear($this->beginningOfTimeLastNInYears); $idSite = $segmentInfo['enable_only_idsite'] ?? null; if (!empty($idSite)) { $siteCreationDate = Date::factory(Site::getCreationDateFor($idSite)); if ($result->isEarlier($siteCreationDate)) { $result = $siteCreationDate; } } $earliestVisitTime = $this->getEarliestVisitTimeFor($idSite); if (!empty($earliestVisitTime) && $result->isEarlier($earliestVisitTime) ) { $result = $earliestVisitTime; } return $result; } } private function getCreatedTimeOfSegment($storedSegment) { // check for an earlier ts_created timestamp $createdTime = empty($storedSegment['ts_created']) ? null : Date::factory($storedSegment['ts_created']); // if there is no ts_last_edit timestamp, initialize it to ts_created if (empty($storedSegment['ts_last_edit'])) { $storedSegment['ts_last_edit'] = empty($storedSegment['ts_created']) ? null : $storedSegment['ts_created']; } // check for a later ts_last_edit timestamp $lastEditTime = empty($storedSegment['ts_last_edit']) ? null : Date::factory($storedSegment['ts_last_edit']); return array($createdTime, $lastEditTime); } private function getEarliestVisitTimeFor($idSite) { $earliestIdVisit = Db::fetchOne('SELECT idvisit FROM ' . Common::prefixTable('log_visit') . ' WHERE idsite = ? ORDER BY visit_last_action_time ASC LIMIT 1', [$idSite]); $earliestStartTime = Db::fetchOne('SELECT visit_first_action_time FROM ' . Common::prefixTable('log_visit') . ' WHERE idvisit = ?', [ $earliestIdVisit, ]); if (empty($earliestStartTime)) { return null; } return Date::factory($earliestStartTime); } public function getAllSegments() { if (!$this->segmentListCache->contains('all')) { $segments = $this->segmentEditorModel->getAllSegmentsAndIgnoreVisibility(); $this->segmentListCache->save('all', $segments); } return $this->segmentListCache->fetch('all'); } public function getAllSegmentsToArchive($idSite) { return Rules::getSegmentsToProcess([$idSite]); } public static function isSegmentForSite($segment, $idSite) { return $segment['enable_only_idsite'] == 0 || $segment['enable_only_idsite'] == $idSite; } public function isAutoArchivingEnabledFor($storedSegment) { return $this->forceArchiveAllSegments || !empty($storedSegment['auto_archive']); } public static function getShouldForceArchiveAllSegments() { return !Rules::isBrowserTriggerEnabled() && !Rules::isBrowserArchivingAvailableForSegments(); } public function reArchiveSegment($segmentInfo) { if (empty($segmentInfo['definition'])) { // sanity check return; } $definition = $segmentInfo['definition']; $idSite = !empty($segmentInfo['enable_only_idsite']) ? $segmentInfo['enable_only_idsite'] : 'all'; $idSites = Access::doAsSuperUser(function () use ($idSite) { return Site::getIdSitesFromIdSitesString($idSite); }); $startDate = $this->getReArchiveSegmentStartDate($segmentInfo); $invalidator = StaticContainer::get(ArchiveInvalidator::class); $invalidator->scheduleReArchiving($idSites, null, null, $startDate, new Segment($definition, $idSites)); } }