/** * Returns date/time like Today, 10:00 AM * * @param $datetime * @param string $timezone * @param string $fromFormat */ public function toText($datetime, $timezone = 'local', $fromFormat = 'Y-m-d H:i:s') { if (empty($datetime)) { return ''; } $this->helper->setDateTime($datetime, $fromFormat, $timezone); $textDate = $this->helper->getTextDate(); $dt = $this->helper->getLocalDateTime(); if ($textDate) { return $this->translator->trans('mautic.core.date.' . $textDate, array('%time%' => $dt->format("g:i a"))); } else { $interval = $this->helper->getDiff('now', null, true); return $this->translator->trans('mautic.core.date.ago', array('%days%' => $interval->days)); } }
/** * Returns date/time like Today, 10:00 AM * * @param $datetime * @param string $timezone * @param string $fromFormat * @param bool $forceDateForNonText If true, return as full date/time rather than "29 days ago" * * @return string */ public function toText($datetime, $timezone = 'local', $fromFormat = 'Y-m-d H:i:s', $forceDateForNonText = false) { if (empty($datetime)) { return ''; } $this->helper->setDateTime($datetime, $fromFormat, $timezone); $textDate = $this->helper->getTextDate(); $dt = $this->helper->getLocalDateTime(); if ($textDate) { return $this->translator->trans('mautic.core.date.' . $textDate, array('%time%' => $dt->format("g:i a"))); } else { $interval = $this->helper->getDiff('now', null, true); if ($interval->invert && !$forceDateForNonText) { // In the past return $this->translator->trans('mautic.core.date.ago', array('%days%' => $interval->days)); } else { // In the future return $this->toFullConcat($datetime, $timezone, $fromFormat); } } }
/** * Check the publish status of an entity based on publish up and down datetimes * * @return string early|expired|published|unpublished * @throws \BadMethodCallException */ public function getPublishStatus() { $dt = new DateTimeHelper(); $current = $dt->getLocalDateTime(); if (!$this->isPublished(false)) { return 'unpublished'; } $status = 'published'; if (method_exists($this, 'getPublishUp')) { $up = $this->getPublishUp(); if (!empty($up) && $current <= $up) { $status = 'pending'; } } if (method_exists($this, 'getPublishDown')) { $down = $this->getPublishDown(); if (!empty($down) && $current >= $down) { $status = 'expired'; } } return $status; }
/** * Rebuild lead lists * * @param LeadList $entity * @param int $limit * @param bool $maxLeads * @param OutputInterface $output * * @return int */ public function rebuildListLeads(LeadList $entity, $limit = 1000, $maxLeads = false, OutputInterface $output = null) { defined('MAUTIC_REBUILDING_LEAD_LISTS') or define('MAUTIC_REBUILDING_LEAD_LISTS', 1); $id = $entity->getId(); $list = array('id' => $id, 'filters' => $entity->getFilters()); $dtHelper = new DateTimeHelper(); $batchLimiters = array('dateTime' => $dtHelper->toUtcString()); $localDateTime = $dtHelper->getLocalDateTime(); // Get a count of leads to add $newLeadsCount = $this->getLeadsByList($list, true, array('countOnly' => true, 'newOnly' => true, 'batchLimiters' => $batchLimiters)); // Ensure the same list is used each batch $batchLimiters['maxId'] = (int) $newLeadsCount[$id]['maxId']; // Number of total leads to process $leadCount = (int) $newLeadsCount[$id]['count']; if ($output) { $output->writeln($this->translator->trans('mautic.lead.list.rebuild.to_be_added', array('%leads%' => $leadCount, '%batch%' => $limit))); } // Handle by batches $start = $lastRoundPercentage = $leadsProcessed = 0; // Try to save some memory gc_enable(); if ($leadCount) { $maxCount = $maxLeads ? $maxLeads : $leadCount; if ($output) { $progress = ProgressBarHelper::init($output, $maxCount); $progress->start(); } // Add leads while ($start < $leadCount) { // Keep CPU down for large lists; sleep per $limit batch $this->batchSleep(); $newLeadList = $this->getLeadsByList($list, true, array('newOnly' => true, 'limit' => $limit, 'batchLimiters' => $batchLimiters)); if (empty($newLeadList[$id])) { // Somehow ran out of leads so break out break; } foreach ($newLeadList[$id] as $l) { $this->addLead($l, $entity, false, true, -1, $localDateTime); unset($l); $leadsProcessed++; if ($output && $leadsProcessed < $maxCount) { $progress->setProgress($leadsProcessed); } if ($maxLeads && $leadsProcessed >= $maxLeads) { break; } } $start += $limit; // Dispatch batch event if ($this->dispatcher->hasListeners(LeadEvents::LEAD_LIST_BATCH_CHANGE)) { $event = new ListChangeEvent($newLeadList[$id], $entity, true); $this->dispatcher->dispatch(LeadEvents::LEAD_LIST_BATCH_CHANGE, $event); unset($event); } unset($newLeadList); // Free some memory gc_collect_cycles(); if ($maxLeads && $leadsProcessed >= $maxLeads) { if ($output) { $progress->finish(); $output->writeln(''); } return $leadsProcessed; } } if ($output) { $progress->finish(); $output->writeln(''); } } // Get a count of leads to be removed $removeLeadCount = $this->getLeadsByList($list, true, array('countOnly' => true, 'nonMembersOnly' => true, 'batchLimiters' => $batchLimiters)); // Restart batching $start = $lastRoundPercentage = 0; $leadCount = $removeLeadCount[$id]['count']; if ($output) { $output->writeln($this->translator->trans('mautic.lead.list.rebuild.to_be_removed', array('%leads%' => $leadCount, '%batch%' => $limit))); } if ($leadCount) { $maxCount = $maxLeads ? $maxLeads : $leadCount; if ($output) { $progress = ProgressBarHelper::init($output, $maxCount); $progress->start(); } // Remove leads while ($start < $leadCount) { // Keep CPU down for large lists; sleep per $limit batch $this->batchSleep(); $removeLeadList = $this->getLeadsByList($list, true, array('limit' => $limit, 'nonMembersOnly' => true, 'batchLimiters' => $batchLimiters)); if (empty($removeLeadList[$id])) { // Somehow ran out of leads so break out break; } foreach ($removeLeadList[$id] as $l) { $this->removeLead($l, $entity, false, true, true); $leadsProcessed++; if ($output && $leadsProcessed < $maxCount) { $progress->setProgress($leadsProcessed); } if ($maxLeads && $leadsProcessed >= $maxLeads) { break; } } // Dispatch batch event if ($this->dispatcher->hasListeners(LeadEvents::LEAD_LIST_BATCH_CHANGE)) { $event = new ListChangeEvent($removeLeadList[$id], $entity, false); $this->dispatcher->dispatch(LeadEvents::LEAD_LIST_BATCH_CHANGE, $event); unset($event); } $start += $limit; unset($removeLeadList); // Free some memory gc_collect_cycles(); if ($maxLeads && $leadsProcessed >= $maxLeads) { if ($output) { $progress->finish(); $output->writeln(''); } return $leadsProcessed; } } if ($output) { $progress->finish(); $output->writeln(''); } } return $leadsProcessed; }
/** * @param QueryBuilder $query DBAL QueryBuilder * @param array $options Query optons from LeadTimelineEvent * @param $eventNameColumn Name of column to sort event name by * @param $timestampColumn Name of column to sort timestamp by * @param array $serializedColumns Array of columns to unserialize * @param array $dateTimeColumns Array of columns to be converted to \DateTime * @param null $resultsParserCallback Callback to custom parse results * * @return array */ private function getTimelineResults(QueryBuilder $query, array $options, $eventNameColumn, $timestampColumn, $serializedColumns = [], $dateTimeColumns = [], $resultsParserCallback = null) { if (!empty($options['unitCounts'])) { list($tablePrefix, $column) = explode('.', $timestampColumn); // Get counts grouped by unit based on date range /** @var ChartQuery $cq */ $cq = $options['chartQuery']; $cq->modifyTimeDataQuery($query, $column, $tablePrefix); $cq->applyDateFilters($query, $column, $tablePrefix); $data = $query->execute()->fetchAll(); $data = $cq->completeTimeData($data); return $data; } if (!empty($options['fromDate']) && !empty($options['toDate'])) { $query->andWhere($timestampColumn . ' BETWEEN :dateFrom AND :dateTo')->setParameter('dateFrom', $options['fromDate']->format('Y-m-d H:i:s'))->setParameter('dateTo', $options['toDate']->format('Y-m-d H:i:s')); } elseif (!empty($options['fromDate'])) { $query->andWhere($query->expr()->gte('fs.date_submitted', ':dateFrom'))->setParameter('dateFrom', $options['fromDate']->format('Y-m-d H:i:s')); } elseif (!empty($options['toDate'])) { $query->andWhere($query->expr()->lte('fs.date_submitted', ':dateTo'))->setParameter('dateTo', $options['toDate']->format('Y-m-d H:i:s')); } if (isset($options['leadIds'])) { $leadColumn = $this->getTableAlias() . '.lead_id'; $query->addSelect($leadColumn); $query->andWhere($query->expr()->in($leadColumn, $options['leadIds'])); } if (isset($options['order'])) { list($orderBy, $orderByDir) = $options['order']; switch ($orderBy) { case 'eventLabel': $orderBy = $eventNameColumn; break; case 'timestamp': default: $orderBy = $timestampColumn; break; } $query->orderBy($orderBy, $orderByDir); } if (!empty($options['limit'])) { $query->setMaxResults($options['limit']); if (!empty($options['start'])) { $query->setFirstResult($options['start']); } } $results = $query->execute()->fetchAll(); if (!empty($serializedColumns) || !empty($dateTimeColumns) || is_callable($resultsParserCallback)) { // Convert to array or \DateTime since we're using DBAL here foreach ($results as &$result) { foreach ($serializedColumns as $col) { if (isset($result[$col])) { $result[$col] = null == $result[$col] ? [] : unserialize($result[$col]); } } foreach ($dateTimeColumns as $col) { if (isset($result[$col]) && !empty($result[$col])) { $dt = new DateTimeHelper($result[$col], 'Y-m-d H:i:s', 'UTC'); $result[$col] = $dt->getLocalDateTime(); unset($dt); } } if (is_callable($resultsParserCallback)) { $resultsParserCallback($result); } } } if (!empty($options['paginated'])) { // Get a total count along with results $query->resetQueryParts(['select', 'orderBy'])->setFirstResult(null)->setMaxResults(null)->select('count(*)'); $total = $query->execute()->fetchColumn(); return ['total' => $total, 'results' => $results]; } return $results; }