[ 'name' => NewsletterOptionFieldEntity::NAME_FILTER_SEGMENT_ID, 'newsletter_type' => NewsletterEntity::TYPE_NOTIFICATION, ], ]; return [ 'rows' => $optionFields, 'identification_columns' => [ 'name', 'newsletter_type', ], ]; } protected function newsletterTemplates() { $templates = []; foreach ($this->templates as $template) { $template = self::TEMPLATES_NAMESPACE . $template; $template = new $template(Env::$assetsUrl); $templates[] = $template->get(); } return [ 'rows' => $templates, 'identification_columns' => [ 'name', ], 'remove_duplicates' => true, ]; } protected function populate($model) { $modelMethod = Helpers::underscoreToCamelCase($model); $table = $this->prefix . $model; $dataDescriptor = $this->$modelMethod(); $rows = $dataDescriptor['rows']; $identificationColumns = array_fill_keys( $dataDescriptor['identification_columns'], '' ); $removeDuplicates = isset($dataDescriptor['remove_duplicates']) && $dataDescriptor['remove_duplicates']; foreach ($rows as $row) { $existenceComparisonFields = array_intersect_key( $row, $identificationColumns ); if (!$this->rowExists($table, $existenceComparisonFields)) { $this->insertRow($table, $row); } else { if ($removeDuplicates) { $this->removeDuplicates($table, $row, $existenceComparisonFields); } $this->updateRow($table, $row, $existenceComparisonFields); } } } private function rowExists(string $tableName, array $columns): bool { global $wpdb; $conditions = array_map(function($key, $value) { return esc_sql($key) . "='" . esc_sql($value) . "'"; }, array_keys($columns), $columns); $table = esc_sql($tableName); // $conditions is escaped // phpcs:ignore WordPressDotOrg.sniffs.DirectDB.UnescapedDBParameter return $wpdb->get_var( "SELECT COUNT(*) FROM $table WHERE " . implode(' AND ', $conditions) ) > 0; } private function insertRow($table, $row) { global $wpdb; return $wpdb->insert( $table, $row ); } private function updateRow($table, $row, $where) { global $wpdb; return $wpdb->update( $table, $row, $where ); } private function removeDuplicates($table, $row, $where) { global $wpdb; $conditions = ['1=1']; $values = []; foreach ($where as $field => $value) { $conditions[] = "`t1`.`" . esc_sql($field) . "` = `t2`.`" . esc_sql($field) . "`"; $conditions[] = "`t1`.`" . esc_sql($field) . "` = %s"; $values[] = $value; } $conditions = implode(' AND ', $conditions); $table = esc_sql($table); return $wpdb->query( $wpdb->prepare( "DELETE t1 FROM $table t1, $table t2 WHERE t1.id < t2.id AND $conditions", $values ) ); } private function createSourceForSubscribers() { $statisticsFormTable = $this->entityManager->getClassMetadata(StatisticsFormEntity::class)->getTableName(); $subscriberTable = $this->entityManager->getClassMetadata(SubscriberEntity::class)->getTableName(); $this->entityManager->getConnection()->executeStatement( ' UPDATE LOW_PRIORITY `' . $subscriberTable . '` subscriber ' . ' JOIN `' . $statisticsFormTable . '` stats ON stats.subscriber_id=subscriber.id ' . ' SET `source` = "' . Source::FORM . '"' . ' WHERE `source` = "' . Source::UNKNOWN . '"' ); $this->entityManager->getConnection()->executeStatement( 'UPDATE LOW_PRIORITY `' . $subscriberTable . '`' . ' SET `source` = "' . Source::WORDPRESS_USER . '"' . ' WHERE `source` = "' . Source::UNKNOWN . '"' . ' AND `wp_user_id` IS NOT NULL' ); $this->entityManager->getConnection()->executeStatement( 'UPDATE LOW_PRIORITY `' . $subscriberTable . '`' . ' SET `source` = "' . Source::WOOCOMMERCE_USER . '"' . ' WHERE `source` = "' . Source::UNKNOWN . '"' . ' AND `is_woocommerce_user` = 1' ); } private function scheduleInitialInactiveSubscribersCheck() { $this->scheduleTask( InactiveSubscribers::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp'))->addHour() ); } private function scheduleAuthorizedSendingEmailsCheck() { if (!Bridge::isMPSendingServiceEnabled()) { return; } $this->scheduleTask( AuthorizedSendingEmailsCheck::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } private function scheduleBeamer() { if (!$this->settings->get('last_announcement_date')) { $this->scheduleTask( Beamer::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } } private function scheduleUnsubscribeTokens() { $this->scheduleTask( UnsubscribeTokens::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } private function scheduleSubscriberLinkTokens() { $this->scheduleTask( SubscriberLinkTokens::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } private function scheduleMixpanel() { $this->scheduleTask(Mixpanel::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp'))); } private function scheduleTask($type, $datetime, $priority = null) { $task = $this->scheduledTasksRepository->findOneBy( [ 'type' => $type, 'status' => [ScheduledTaskEntity::STATUS_SCHEDULED, null], ] ); if ($task) { return true; } $task = new ScheduledTaskEntity(); $task->setType($type); $task->setStatus(ScheduledTaskEntity::STATUS_SCHEDULED); $task->setScheduledAt($datetime); if ($priority !== null) { $task->setPriority($priority); } $this->scheduledTasksRepository->persist($task); $this->scheduledTasksRepository->flush(); } private function detectReferral() { $this->referralDetector->detect(); } private function scheduleSubscriberLastEngagementDetection() { if (version_compare((string)$this->settings->get('db_version', '3.72.1'), '3.72.0', '>')) { return; } $this->scheduleTask( SubscribersLastEngagement::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } private function scheduleNewsletterTemplateThumbnails() { $this->scheduleTask( NewsletterTemplateThumbnails::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')), ScheduledTaskEntity::PRIORITY_LOW ); } private function scheduleBackfillEngagementData(): void { $existingTask = $this->scheduledTasksRepository->findOneBy( [ 'type' => BackfillEngagementData::TASK_TYPE, ] ); if ($existingTask) { return; } $this->scheduleTask( BackfillEngagementData::TASK_TYPE, Carbon::createFromTimestamp($this->wp->currentTime('timestamp')) ); } }