Nav::parseNavReference()   B
last analyzed

Complexity

Conditions 6
Paths 9

Size

Total Lines 26
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 26
rs 8.439
c 0
b 0
f 0
cc 6
eloc 17
nc 9
nop 2
1
<?php
2
3
/*
4
 * This file is part of the ReportBundle package
5
 *
6
 * (c) symball <http://simonball.me>
7
 *
8
 * For the full copyright and license information, please view the LICENSE file
9
 * that was distributed with this source code.
10
 */
11
12
13
namespace Symball\ReportBundle\Service;
14
15
/**
16
 * The navigation service is responsible for handling the position of the
17
 * spreadsheet pointer
18
 *
19
 * @author Simon Ball <simonball at simonball dot me>
20
 */
21
abstract class Nav
22
{
23
24
    /**
25
     * @var int Used to determine the initial column
26
     */
27
    protected $columnInitial;
28
29
    /**
30
     * @var int Used to determine the initial row
31
     */
32
    protected $rowInitial;
33
34
    /**
35
     * @var int Tracks the column to go to when the user resets
36
     */
37
    protected $columnSetStart;
38
39
    /**
40
     * @var int Tracks the row to go to when the user resets
41
     */
42
    protected $rowSetStart;
43
44
    /**
45
     * @var int Head column
46
     */
47
    protected $columnCurrent;
48
49
    /**
50
     * @var int Head row
51
     */
52
    protected $rowCurrent;
53
54
    protected $status = 'initial';
55
56
    protected $columnCount = 0;
57
58
    /**
59
     * @param int $columnInitial Determine the starting column to use
60
     * @param int $rowInitial    Determine the starting row to use
61
     */
62
    public function __construct($columnInitial = 2, $rowInitial = 3)
63
    {
64
        // Set all tracking data to the preset
65
        $this->columnInitial = $this->columnSetStart = $this->columnCurrent = $columnInitial;
66
        $this->rowInitial = $this->rowSetStart = $this->rowCurrent = $rowInitial;
67
    }
68
69
    /**
70
     * Move the cursor position to the starting area for the next data point or
71
     * later depending on the argument passed
72
     *
73
     * @param integer $count
74
     * @return $this
75
     */
76
    public function movePointerAlong($count = 1)
77
    {
78
79
        $this
80
        ->columnReset('set')
81
        ->rowReset('initial')
82
        ->axisYMove($count)
83
        ->setStartColumn();
84
85
        return $this;
86
    }
87
88
    /**
89
     * @return string Get the current coordinates in an excel friendly manner
90
     */
91
    public function __toString()
92
    {
93
        return $this->coord();
94
    }
95
96
    /**
97
     * Move the pointer up x (default 1) amount of places.
98
     *
99
     * @param int $placesToMove
100
     * @return $this
101
     */
102
    public function up($placesToMove = 1)
103
    {
104
        // Check for validity of movement
105
        if (0 >= ($this->rowCurrent - $placesToMove)) {
106
            throw new \Exception('Movement would go out of bounds');
107
        }
108
        $this->rowCurrent -= $placesToMove;
109
110
        return $this;
111
    }
112
113
    /**
114
     * Move the pointer right x (default 1) amount of places.
115
     *
116
     * @param int $placesToMove
117
     * @return $this
118
     */
119
    public function right($placesToMove = 1)
120
    {
121
        $this->columnCurrent += $placesToMove;
122
123
        return $this;
124
    }
125
126
    /**
127
     * Move the pointer down x (default 1) amount of places.
128
     *
129
     * @param int $placesToMove
130
     *
131
     * @return $this
132
     */
133
    public function down($placesToMove = 1)
134
    {
135
        $this->rowCurrent += $placesToMove;
136
137
        return $this;
138
    }
139
140
    /**
141
     * Move the pointer left x (default 1) amount of places.
142
     *
143
     * @param int $placesToMove
144
     *
145
     * @return $this
146
     */
147
    public function left($placesToMove = 1)
148
    {
149
        if (0 >= ($this->columnCurrent - $placesToMove)) {
150
            throw new \Exception('Movement would go out of bounds');
151
        }
152
153
        $this->columnCurrent -= $placesToMove;
154
155
        return $this;
156
    }
157
158
    /**
159
     * Reset the row pointer to starting area of either spreadsheet or set
160
     *
161
     * @param string $type
162
     * @return $this
163
     */
164
    public function rowReset($type = 'initial')
165
    {
166
        switch ($type) {
167
            case 'initial':
168
                $this->rowCurrent = $this->rowSetStart = $this->rowInitial;
169
                break;
170
171
            case 'set':
172
                $this->rowCurrent = $this->rowSetStart;
173
                break;
174
175
            default:
176
                break;
177
        }
178
179
        return $this;
180
    }
181
182
    /**
183
     * Reset the column pointer to starting area of either spreadsheet or set
184
     *
185
     * @param string $type
186
     * @return $this
187
     */
188
    public function columnReset($type = 'initial')
189
    {
190
        switch ($type) {
191
            case 'initial':
192
                $this->columnCurrent = $this->columnSetStart = $this->columnInitial;
193
                break;
194
195
            case 'set':
196
                $this->columnCurrent = $this->columnSetStart;
197
                break;
198
199
            default:
200
                break;
201
        }
202
203
        return $this;
204
    }
205
206
    /**
207
     * Reset both the and column pointer to either spreadsheet or set
208
     *
209
     * @param string $type The human friendly syntax for what position to use
210
     * @return $this
211
     */
212
    public function reset($type = 'intitial')
213
    {
214
        $this->rowReset($type);
215
        $this->columnReset($type);
216
217
        return $this;
218
    }
219
220
    /**
221
     * Update the current entry for what is considered the starting column.
222
     *
223
     * @return $this
224
     */
225
    public function setStartColumn()
226
    {
227
        $this->columnSetStart = $this->columnCurrent;
228
229
        return $this;
230
    }
231
232
    /**
233
     * Get the spreadsheet object coord from a numeric value
234
     * If no parameters are used, the context coord will be returned.
235
     *
236
     * @param string|integer $column Either integer index or human friendly syntax
237
     * @param string|integer $row    Either integer index or human friendly syntax
238
     *
239
     * @return string|interger [description]
240
     */
241
    public function coord($column = false, $row = false)
242
    {
243
        if (!$column) {
244
            $column = $this->columnCurrent;
245
        }
246
        if (!$row) {
247
            $row = $this->rowCurrent;
248
        }
249
250
        $column = $this->parseNavReference($column, 'column');
251
        $row = $this->parseNavReference($row, 'row');
252
253
        return $this->nmbToClm($column) . $row;
254
    }
255
256
    /**
257
     * Parse a number in to letter format.
258
     *
259
     * @param int $num
260
     *
261
     * @return string
262
     */
263
    public function nmbToClm($num)
264
    {
265
        $numeric = ($num - 1) % 26;
266
        $letter = chr(65 + $numeric);
267
        $num2 = intval(($num - 1) / 26);
268
        if ($num2 > 0) {
269
            return $this->nmbToClm($num2) . $letter;
270
        } else {
271
            return $letter;
272
        }
273
    }
274
275
    /**
276
     * A helper function for returning numerical coordinates.
277
     *
278
     * @param string $input
279
     * @param string $axis
280
     *
281
     * @return integer
282
     */
283
    public function parseNavReference($input = '', $axis = 'column')
284
    {
285
        switch ($input) {
286
            case 'initial':
287
                $propertyName = $axis . 'Initial';
288
                break;
289
290
            case 'set':
291
                $propertyName = $axis . 'Start';
292
                break;
293
294
            case 'current':
295
                $propertyName = $axis . 'Current';
296
                break;
297
298
            default:
299
                if (is_int($input)) {
300
                    return $input;
301
                }
302
                break;
303
        }
304
305
        if(isset($propertyName)) {
306
          return $this->$propertyName;
307
        }
308
    }
309
310
    /**
311
     * Return the column value according to various criteria, defaulting to
312
     * current.
313
     *
314
     * @param string $type
315
     * @param bool   $asLetter
316
     *
317
     * @return string|integer The column pointer as either index or letter
318
     */
319
    public function column($type = 'current', $asLetter = false)
320
    {
321
        if ($type == false || $type == '') {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $type of type string to the boolean false. If you are specifically checking for an empty string, consider using the more explicit === '' instead.
Loading history...
322
            $type = 'current';
323
        }
324
325
        $column = $this->parseNavReference($type);
326
327
        if ($asLetter) {
328
            return $this->nmbToClm($column);
329
        } else {
330
            return $column;
331
        }
332
    }
333
334
    /**
335
     * Return the row value according to various criteria, defaulting to current.
336
     *
337
     * @param string $type
338
     *
339
     * @return int The row index
340
     */
341
    public function row($type = 'current')
342
    {
343
        return $this->parseNavReference($type, 'row');
344
    }
345
}
346