Completed
Pull Request — master (#3)
by Bernhard
12:11
created

File   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 170
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 12
Bugs 3 Features 5
Metric Value
wmc 25
c 12
b 3
f 5
lcom 1
cbo 2
dl 0
loc 170
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 2
A getLogFilePath() 0 4 1
A store() 0 10 1
A getStorageContent() 0 4 1
F retrieve() 0 75 20
1
<?php
2
3
/**
4
 * \Wicked\Timely\Storage\File
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Bernhard Wick <[email protected]>
15
 * @copyright 2016 Bernhard Wick
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/wick-ed/timely
18
 */
19
20
namespace Wicked\Timely\Storage;
21
22
use Wicked\Timely\Entities\Booking;
23
use Wicked\Timely\Entities\Clipping;
24
use Wicked\Timely\Formatter\FormatterFactory;
25
use Wicked\Timely\Entities\BookingFactory;
26
27
/**
28
 * File storage
29
 *
30
 * @author    Bernhard Wick <[email protected]>
31
 * @copyright 2016 Bernhard Wick
32
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
33
 * @link      https://github.com/wick-ed/timely
34
 */
35
class File implements StorageInterface
36
{
37
38
    /**
39
     * Default character for a line break in the format
40
     *
41
     * @var string LINE_BREAK
42
     */
43
    const LINE_BREAK = ';';
44
45
    /**
46
     * Default character sequence for segment separation
47
     *
48
     * @var string SEPARATOR
49
     */
50
    const SEPARATOR = ' | ';
51
52
    /**
53
     * Name of the log file
54
     *
55
     * @var string DATA_NAME
56
     */
57
    const DATA_NAME = 'timely-log.txt';
58
59
    /**
60
     * Path to the log file
61
     *
62
     * @var string $logFilePath
63
     */
64
    protected $logFilePath;
65
66
    /**
67
     * Default constructor
68
     */
69
    public function __construct()
70
    {
71
        // calculate the default file path
72
        $this->logFilePath = dirname(dirname(__DIR__)) . DIRECTORY_SEPARATOR . 'data' . DIRECTORY_SEPARATOR . self::DATA_NAME;
73
        // check if the file exists, if not create it
74
        if (!is_file($this->logFilePath)) {
75
            touch($this->logFilePath);
76
        }
77
    }
78
79
    /**
80
     * Getter for the log file path
81
     *
82
     * @return string
83
     */
84
    public function getLogFilePath()
85
    {
86
        return $this->logFilePath;
87
    }
88
89
    /**
90
     * Stores a single booking
91
     *
92
     * @param \Wicked\Timely\Entities\Booking $booking The booking to store
93
     *
94
     * @return void
95
     */
96
    public function store(Booking $booking)
97
    {
98
        // get the formatter and convert to string
99
        $formatter = FormatterFactory::getFormatter();
100
        $bookString = $formatter->toString($booking);
101
102
        // write the new booking to the beginning of the file
103
        $path = $this->getLogFilePath();
104
        file_put_contents($path, $bookString . file_get_contents($path));
105
    }
106
107
    /**
108
     * Get the content of the files storage
109
     *
110
     * @return string
111
     */
112
    protected function getStorageContent()
113
    {
114
        return file_get_contents($this->getLogFilePath());
115
    }
116
117
    /**
118
     * Retrieves one or several bookings from the storage. Bookings can be filtered by pattern,
119
     * date, etc.
120
     *
121
     * @param null|string  $pattern  A pattern to filter ticket IDs for. Defaults to NULL
122
     * @param null|integer $toDate   Date up to which bookings will be returned. Defaults to NULL
123
     * @param null|integer $fromDate Date from which on bookings will be returned. Defaults to NULL
124
     * @param null|integer $limit    Number of non-meta bookings the retrieval is limited to. Defaults to NULL
125
     * @param boolean      $dontClip Whether or not the retrieved bookings should be clipped where appropriate. Defaults to FALSE
126
     *
127
     * @return \Wicked\Timely\Entities\Booking[]
128
     */
129
    public function retrieve($pattern = null, $toDate = null, $fromDate = null, $limit = null, $dontClip = false)
130
    {
131
        // test if we got a pattern, if not match against all
132
        if (is_null($pattern)) {
133
            $pattern = '*';
134
        }
135
        // test if we got some dates to filter by
136
        if (is_null($toDate)) {
137
            $toDate = 9999999999;
138
        }
139
        if (is_null($fromDate)) {
140
            $fromDate = 0;
141
        }
142
143
        // get the raw entries
144
        $rawData = $this->getStorageContent();
145
        $rawEntries = explode(self::LINE_BREAK, rtrim($rawData, self::LINE_BREAK));
146
147
        $entries = array();
148
149
        // if clipping is not omitted we will add the rear clipping to our collection
150
        if (!$dontClip) {
151
            $entries[] = BookingFactory::getBooking('', Clipping::CLIPPING_TAG_REAR);
152
        }
153
154
        // iterate them and generate the entities
155
        $bookingKey = null;
156
        $bookingCount = 0;
157
        foreach ($rawEntries as $key => $rawEntry) {
158
            // get the potential entry and filter them by ticket ID
159
            $entry = explode(self::SEPARATOR, trim($rawEntry, ' |'));
160
            $timestamp = strtotime($entry[0]);
161
            if (isset($entry[1]) &&
162
                (fnmatch($pattern, $entry[1]) || isset(BookingFactory::getAllMetaTicketIds()[$entry[1]])) &&
163
                $timestamp > $fromDate && $timestamp < $toDate
164
            ) {
165
                // collect the actual booking
166
                $comment = isset($entry[2]) ? $entry[2] : '';
167
                $booking = BookingFactory::getBooking($comment, $entry[1], $entry[0]);
168
                $entries[] = $booking;
169
170
                // increase the booking counter
171
                if (!$booking->isMetaBooking()) {
172
                    $bookingCount ++;
173
                }
174
175
                // collect keys we found something for, for later re-use
176
                $bookingKey = $key;
177
178
                // break if we got as much bookings as our limit is
179
                if (!is_null($limit) && $limit <= $bookingCount) {
180
                    break;
181
                }
182
            }
183
        }
184
185
        // clip the front, but only if we filter by from date
186
        if (!$dontClip && $fromDate !== 0) {
187
            $entries[] = BookingFactory::getBooking('', Clipping::CLIPPING_TAG_FRONT, $fromDate);
188
189
            // move some bookings into the past to get the startbooking of a potential task we might need
190
            for ($i = $bookingKey + 1; $i < count($rawEntries); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
191
                $entry = explode(self::SEPARATOR, trim($rawEntries[$i], ' |'));
192
                $comment = isset($entry[2]) ? $entry[2] : '';
193
                $booking = BookingFactory::getBooking($comment, $entry[1], $entry[0]);
194
                $entries[] = $booking;
195
                // break after the first non-meta booking
196
                if (!$booking->isMetaBooking()) {
197
                    break;
198
                }
199
            }
200
        }
201
202
        return $entries;
203
    }
204
}
205