Passed
Pull Request — master (#347)
by Mirko
07:40
created

FieldNoteService::importFromFile()   B

Complexity

Conditions 8
Paths 11

Size

Total Lines 57
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 36
c 0
b 0
f 0
nc 11
nop 3
dl 0
loc 57
rs 7.2648

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace AppBundle\Service;
4
5
use AppBundle\Entity\FieldNote;
6
use AppBundle\Exception\WrongFileFormatException;
7
use AppBundle\Service\Interfaces\FieldNoteServiceInterface;
8
use AppBundle\Service\Traits\ErrorTrait;
9
use AppBundle\Util\ArrayUtil;
10
use AppBundle\Util\DateUtil;
11
use DateTime;
12
use DateTimeZone;
13
use Doctrine\ORM\EntityManagerInterface;
14
use Symfony\Component\Translation\TranslatorInterface;
15
16
class FieldNoteService implements FieldNoteServiceInterface
17
{
18
    use ErrorTrait;
19
20
    /**
21
     * @var \Doctrine\ORM\EntityManagerInterface
22
     */
23
    protected $entityManager;
24
25
    /**
26
     * @var \Symfony\Component\Translation\TranslatorInterface
27
     */
28
    protected $translator;
29
30
    /**
31
     * FieldNoteService constructor.
32
     *
33
     * @param \Doctrine\ORM\EntityManagerInterface $entityManager
34
     * @param \Symfony\Component\Translation\TranslatorInterface $translator
35
     */
36
    public function __construct(EntityManagerInterface $entityManager, TranslatorInterface $translator)
37
    {
38
        $this->entityManager = $entityManager;
39
        $this->translator = $translator;
40
    }
41
42
    /**
43
     * @param string $fileName
44
     * @param int $userId
45
     * @param null|\DateTime $ignoreBeforeDate
46
     *
47
     * @return bool
48
     * @throws \AppBundle\Exception\WrongFileFormatException
49
     */
50
    public function importFromFile($fileName, $userId, DateTime $ignoreBeforeDate = null)
51
    {
52
        $content = file_get_contents($fileName);
53
        $content = mb_convert_encoding($content, 'UTF-8', 'UCS-2LE');
54
        $rows = ArrayUtil::trimExplode("\n", $content);
55
        foreach ($rows as $row) {
56
            $data = str_getcsv($row, ',', '"', '""');
57
            if (count($data) !== 4) {
58
                throw new WrongFileFormatException(
59
                    $this->translator->trans('field_notes.error.wrong_file_format')
60
                );
61
            }
62
63
            $date = DateTime::createFromFormat(
64
                self::FIELD_NOTE_DATETIME_FORMAT,
65
                $data[1],
66
                new DateTimeZone('UTC')
67
            );
68
69
            if ($ignoreBeforeDate !== null && $date < $ignoreBeforeDate) {
70
                continue;
71
            }
72
73
            if (!array_key_exists($data[2], self::LOG_TYPE)) {
74
                $this->addError(
75
                    /** @Desc("Log type ""%type%"" is not implemented.") */
76
                    $this->translator->trans('field_notes.error.log_type_not_implemented', ['%type%' => $data[2]])
77
                );
78
                continue;
79
            }
80
            $type = self::LOG_TYPE[$data[2]];
81
            
82
            $geocache = $this->entityManager->getRepository('AppBundle:Geocache')->findOneBy(['wpOc' => $data[0]]);
83
            if (!$geocache) {
84
                $this->addError(
85
                    /** @Desc("Geocache ""%code%"" not found.") */
86
                    $this->translator->trans('field_notes.error.geocache_not_found', ['%code%' => $data[0]])
87
                );
88
                continue;
89
            }
90
91
            $fieldNote = new FieldNote();
92
            $fieldNote->setUser($this->entityManager->getReference('AppBundle:User', $userId));
93
            $fieldNote->setGeocache($geocache);
94
            $fieldNote->setDate($date);
95
            $fieldNote->setType($type);
96
            $fieldNote->setText($data[3]);
97
            $this->entityManager->persist($fieldNote);
98
        }
99
        $this->entityManager->flush();
100
101
        if ($this->hasErrors()) {
102
            return false;
103
        }
104
105
        return true;
106
    }
107
108
    /**
109
     * @param int $userId
110
     *
111
     * @return \DateTime|null
112
     */
113
    public function getLatestFieldNoteOrLogDate($userId)
114
    {
115
        $maxFieldNote = $this->getMaxDateFromEntityByUserId('AppBundle:FieldNote', $userId);
116
        $maxLog = $this->getMaxDateFromEntityByUserId('AppBundle:GeocacheLog', $userId);
117
118
        return max($maxFieldNote, $maxLog);
119
    }
120
121
    /**
122
     * @param string $entityName
123
     * @param int $userId
124
     *
125
     * @return \DateTime|null
126
     */
127
    protected function getMaxDateFromEntityByUserId($entityName, $userId)
128
    {
129
        $max = null;
130
        $query = $this->entityManager->createQueryBuilder();
131
        $query
132
            ->select('MAX(e.date) AS max_date')
133
            ->from($entityName, 'e')
134
            ->where('e.user = :user_id')
135
                ->setParameter('user_id', $userId)
136
            ->setMaxResults(1);
137
        $result = $query->getQuery()->getResult();
138
        if ($result && isset($result[0]['max_date'])) {
139
            $max = DateUtil::dateTimeFromMySqlFormat($result[0]['max_date']);
140
        }
141
142
        return $max;
143
    }
144
}
145