/**
  * Returns the last date after which the given feed has had a full import.
  *
  * @param Feed $feed
  *
  * @return \DateTime
  */
 public function getLastFullImportDate(Feed $feed)
 {
     // we can only have a full import when the feed is not partial
     if ($feed->isPartial()) {
         return null;
     }
     $imports = $this->getImportRepository()->findCompletedByFeed($feed);
     // find the import dates for this feed, but only non-partial imports
     $dates = [];
     foreach ($imports as $import) {
         // don't count imports with errors
         if ($import->hasErrors()) {
             continue;
         }
         // don't count partial imports
         if ($import->isPartial()) {
             continue;
         }
         // imports without any items are excluded also
         if ($import->getTotalNumberOfItems() === 0) {
             continue;
         }
         $dates[] = $import->getDatetimeStarted();
     }
     // if we have no date for this feed, we can't consider it to be fully imported
     if (empty($dates)) {
         return null;
     }
     // return the latest of the dates
     return max($dates);
 }
 /**
  * Creates an import for a feed. If an import for this feed was created
  * before, but has not started yet, that import is returned. All other open
  * imports are closed first.
  *
  * @param FeedEntity $feed         The feed to create the import for
  * @param \DateTime  $scheduleDate The date this import should start
  * @param bool       $forced       Whether to handle items that would normally be skipped
  * @param bool       $partial      If left out, it will be determined based on feed
  *
  * @throws UnfinishedImportException When an existing (and running) import is found
  *
  * @return Import
  */
 public function createImport(FeedEntity $feed, \DateTime $scheduleDate = null, $forced = false, $partial = null)
 {
     if (is_null($scheduleDate)) {
         $scheduleDate = new \DateTime();
     }
     if (is_null($partial)) {
         $partial = $feed->isPartial();
     }
     // see if any imports are still unfinished
     $import = $this->findOrCreateImport($feed);
     $exception = null;
     // check if it's a new import
     if (!$import->getId()) {
         $import->setForced($forced);
         $import->setPartial($partial);
         $import->setDatetimeScheduled($scheduleDate);
         // save now: we want the import on record before starting it
         $this->getRepository()->save($import);
         // add parts
         try {
             $this->addImportParts($import);
         } catch (\Exception $e) {
             // temporary store the exception, so we can update the import appropriately
             $exception = $e;
         }
     }
     // finish import right away if we have no parts, without parts it would never be started
     if (count($import->getParts()) === 0) {
         $this->getRepository()->startImport($import);
         $this->getRepository()->finishImport($import);
     }
     // throw the exception, because catch all exceptions are evil
     if ($exception) {
         throw $exception;
     }
     return $import;
 }
 /**
  * @param Feed $feed
  *
  * @return array
  */
 protected function getReaderTypeOptions(Feed $feed)
 {
     return array_merge(['partial' => $feed->isPartial(), 'forced' => true], $feed->getReaderOptions());
 }