Completed
Push — master ( 725043...fc3a8f )
by Vladimir
07:42
created

Pulse::getNumericColumn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
/**
4
 * This file contains the Pulse class
5
 *
6
 * @copyright 2015 Vladimir Jimenez
7
 * @license   https://github.com/allejo/PhpPulse/blob/master/LICENSE.md MIT
8
 */
9
10
namespace allejo\DaPulse;
11
12
use allejo\DaPulse\Exceptions\ColumnNotFoundException;
13
use allejo\DaPulse\Exceptions\HttpException;
14
use allejo\DaPulse\Exceptions\InvalidColumnException;
15
use allejo\DaPulse\Exceptions\InvalidObjectException;
16
use allejo\DaPulse\Objects\PulseColumnDateValue;
17
use allejo\DaPulse\Objects\PulseColumnNumericValue;
18
use allejo\DaPulse\Objects\PulseColumnPersonValue;
19
use allejo\DaPulse\Objects\PulseColumnStatusValue;
20
use allejo\DaPulse\Objects\PulseColumnTextValue;
21
use allejo\DaPulse\Objects\PulseColumnValue;
22
use allejo\DaPulse\Objects\SubscribableObject;
23
use allejo\DaPulse\Utilities\ArrayUtilities;
24
25
/**
26
 * A class representing a single pulse in a board
27
 *
28
 * @api
29
 * @package allejo\DaPulse
30
 * @since   0.1.0
31
 */
32
class Pulse extends SubscribableObject
33
{
34
    /**
35
     * @ignore
36
     */
37
    const API_PREFIX = "pulses";
38
39
    // ================================================================================================================
40
    //   Instance Variables
41
    // ================================================================================================================
42
43
    /**
44
     * The resource's URL.
45
     *
46
     * @var string
47
     */
48
    protected $url;
49
50
    /**
51
     * The pulse's name.
52
     *
53
     * @var string
54
     */
55
    protected $name;
56
57
    /**
58
     * The amount of updates a pulse has.
59
     *
60
     * @var int
61
     */
62
    protected $updates_count;
63
64
    /**
65
     * The ID of the parent board.
66
     *
67
     * @var int
68
     */
69
    protected $board_id;
70
71
    /**
72
     * Creation time.
73
     *
74
     * @var \DateTime
75
     */
76
    protected $created_at;
77
78
    /**
79
     * Last update time.
80
     *
81
     * @var \DateTime
82
     */
83
    protected $updated_at;
84
85
    /**
86
     * The ID of the group this pulse belongs to
87
     *
88
     * @var string
89
     */
90
    protected $group_id;
91
92
    /**
93
     * @var PulseColumn[]
94
     */
95
    protected $column_structure;
96
97
    /**
98
     * An array containing all of the values a pulse has for each column
99
     *
100
     * @var mixed
101
     */
102
    protected $raw_column_values;
103
104
    /**
105
     * An array containing objects extended from PulseColumnValue storing all of the values for each column
106
     *
107
     * @var array
108
     */
109
    protected $column_values;
110
111
    /**
112
     * The common URL path for retrieving objects relating a pulse such as subscribers, notes, or updates
113
     *
114
     * @var string
115
     */
116
    private $urlSyntax = "%s/%s/%s.json";
117
118
    // ================================================================================================================
119
    //   Overloaded functions
120
    // ================================================================================================================
121
122
    protected function initializeValues ()
123
    {
124
        $this->column_values     = array();
125
        $this->column_structure  = array();
126
        $this->raw_column_values = array();
127
    }
128
129
    // ================================================================================================================
130
    //   Getter functions
131
    // ================================================================================================================
132
133
    /**
134
     * The resource's URL.
135
     *
136
     * @return string
137
     */
138
    public function getUrl ()
139
    {
140
        return $this->url;
141
    }
142
143
    /**
144
     * The pulse's name.
145
     *
146
     * @return string
147
     */
148
    public function getName ()
149
    {
150
        return $this->name;
151
    }
152
153
    /**
154
     * The amount of updates a pulse has.
155
     *
156
     * @return int
157
     */
158
    public function getUpdatesCount ()
159
    {
160
        return $this->updates_count;
161
    }
162
163
    /**
164
     * The ID of the parent board.
165
     *
166
     * @return int
167
     */
168
    public function getBoardId ()
169
    {
170
        return $this->board_id;
171
    }
172
173
    /**
174
     * Creation time.
175
     *
176
     * @return \DateTime
177
     */
178
    public function getCreatedAt ()
179
    {
180
        self::lazyCast($this->created_at, '\DateTime');
181
182
        return $this->created_at;
183
    }
184
185
    /**
186
     * Last update time.
187
     *
188
     * @return \DateTime
189
     */
190
    public function getUpdatedAt ()
191
    {
192
        self::lazyCast($this->updated_at, '\DateTime');
193
194
        return $this->updated_at;
195
    }
196
197
    /**
198
     * Get the ID of the group this Pulse is a part of. If this value is not available, an API call will be made to
199
     * find the group ID via brute force.
200
     *
201
     * **Note** The group ID is cached if it is not available. To update the cached value, use $forceFetch to force an
202
     * API call to get a new value.
203
     *
204
     * **Warning** An API call is always slower than using the cached value.
205
     *
206
     * @param bool $forceFetch Force an API call to get an updated group ID if it has been changed
207
     *
208
     * @since 0.1.0
209
     * @return string
210
     */
211
    public function getGroupId ($forceFetch = false)
212
    {
213
        if (empty($this->group_id) || $forceFetch)
214
        {
215
            $parentBoard = new PulseBoard($this->board_id);
216
            $pulses      = $parentBoard->getPulses();
217
218
            foreach ($pulses as $pulse)
219
            {
220
                if ($this->getId() === $pulse->getId())
221
                {
222
                    $this->group_id = $pulse->getGroupId();
223
                    break;
224
                }
225
            }
226
        }
227
228
        return $this->group_id;
229
    }
230
231
    // ================================================================================================================
232
    //   Pulse functions
233
    // ================================================================================================================
234
235
    /**
236
     * Edit the name of the pulse
237
     *
238
     * @api
239
     * @param string $title
240
     * @since 0.1.0
241
     */
242
    public function editName($title)
243
    {
244
        $editUrl    = sprintf("%s/%d.json", self::apiEndpoint(), $this->getId());
245
        $postParams = array(
246
            'name' => $title
247
        );
248
249
        $this->jsonResponse = self::sendPut($editUrl, $postParams);
0 ignored issues
show
Documentation Bug introduced by
It seems like self::sendPut($editUrl, $postParams) of type * is incompatible with the declared type array of property $jsonResponse.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
250
        $this->assignResults();
251
    }
252
253
    /**
254
     * Archive the current pulse.
255
     *
256
     * This is the equivalent of a soft delete and can be restored from the DaPulse website.
257
     *
258
     * @api
259
     * @since 0.1.0
260
     */
261
    public function archivePulse()
262
    {
263
        $archiveURL = sprintf("%s/%d.json", self::apiEndpoint(), $this->getId());
264
        $getParams  = array(
265
            'archive' => true
266
        );
267
268
        self::sendDelete($archiveURL, $getParams);
269
    }
270
271
    /**
272
     * Delete the current Pulse
273
     *
274
     * @api
275
     * @throws \allejo\DaPulse\Exceptions\InvalidObjectException
276
     */
277 View Code Duplication
    public function deletePulse ()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
278
    {
279
        $this->checkInvalid();
280
281
        $deleteURL = sprintf("%s/%d.json", self::apiEndpoint(), $this->getId());
282
283
        self::sendDelete($deleteURL);
284
285
        $this->deletedObject = true;
286
    }
287
288
    public function duplicatePulse ($groupId = NULL, $ownerId = NULL)
289
    {
290
        $url        = sprintf("%s/%s/pulses/%s/duplicate.json", self::apiEndpoint("boards"), $this->getBoardId(), $this->getId());
291
        $postParams = array();
292
293
        if ($ownerId instanceof PulseUser)
294
        {
295
            $ownerId = $ownerId->getId();
296
        }
297
298
        self::setIfNotNullOrEmpty($postParams, "group_id", $groupId);
299
        self::setIfNotNullOrEmpty($postParams, "owner_id", $ownerId);
300
301
        $result = self::sendPost($url, $postParams);
302
        $this->pulseInjection($result);
303
304
        return (new Pulse($result['pulse']));
305
    }
306
307 View Code Duplication
    private function pulseInjection (&$result)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
308
    {
309
        $parentBoard = new PulseBoard($this->getBoardId());
310
311
        // Inject some information so a Pulse object can survive on its own
312
        $result["pulse"]["group_id"]          = $result["board_meta"]["group_id"];
313
        $result["pulse"]["column_structure"]  = $parentBoard->getColumns();
314
        $result["pulse"]["raw_column_values"] = $result["column_values"];
315
    }
316
317
    // ================================================================================================================
318
    //   Column data functions
319
    // ================================================================================================================
320
321
    /**
322
     * Access a color type column value belonging to this pulse in order to read it or modify.
323
     *
324
     * This function should only be used to access color type values; an exception will be thrown otherwise.
325
     *
326
     * @api
327
     *
328
     * @param string $columnId The ID of the column to access. This is typically a slugified version of the column name
329
     *
330
     * @since 0.1.0
331
     * @throws InvalidColumnException The specified column is not a "color" type column
332
     * @throws InvalidObjectException The specified column exists but modification of its value is unsupported either
333
     *                                by this library or the DaPulse API.
334
     * @throws InvalidColumnException   The specified column ID does not exist for this Pulse
335
     * @return PulseColumnStatusValue A column object with access to its contents
336
     */
337
    public function getStatusColumn ($columnId)
338
    {
339
        return $this->getColumn($columnId, PulseColumn::Status);
340
    }
341
342
    /**
343
     * Access a date type column value belonging to this pulse in order to read it or modify.
344
     *
345
     * This function should only be used to access data type values; an exception will be thrown otherwise.
346
     *
347
     * @api
348
     *
349
     * @param  string $columnId The ID of the column to access. This is typically a slugified version of the column name
350
     *
351
     * @since  0.1.0
352
     *
353
     * @throws ColumnNotFoundException The specified column ID does not exist for this Pulse
354
     * @throws InvalidColumnException  The specified column is not a "date" type column
355
     * @throws InvalidObjectException  The specified column exists but modification of its value is unsupported either
356
     *                                 by this library or the DaPulse API.
357
     *
358
     * @return PulseColumnDateValue A column object with access to its contents
359
     */
360
    public function getDateColumn ($columnId)
361
    {
362
        return $this->getColumn($columnId, PulseColumn::Date);
363
    }
364
365
    /**
366
     * Access a date type column value belonging to this pulse in order to read it or modify.
367
     *
368
     * This function should only be used to access data type values; an exception will be thrown otherwise.
369
     *
370
     * @api
371
     *
372
     * @param  string $columnId The ID of the column to access. This is typically a slugified version of the column name
373
     *
374
     * @since  0.2.0
375
     *
376
     * @throws ColumnNotFoundException The specified column ID does not exist for this Pulse
377
     * @throws InvalidColumnException  The specified column is not a "numeric" type column
378
     * @throws InvalidObjectException  The specified column exists but modification of its value is unsupported either
379
     *                                 by this library or the DaPulse API.
380
     *
381
     * @return PulseColumnNumericValue A column object with access to its contents
382
     */
383
    public function getNumericColumn ($columnId)
384
    {
385
        return $this->getColumn($columnId, PulseColumn::Numeric);
386
    }
387
388
    /**
389
     * Access a person type column value belonging to this pulse in order to read it or modify.
390
     *
391
     * This function should only be used to access person type values; an exception will be thrown otherwise.
392
     *
393
     * @api
394
     *
395
     * @param  string $columnId The ID of the column to access. This is typically a slugified version of the column name
396
     *
397
     * @since  0.1.0
398
     *
399
     * @throws ColumnNotFoundException The specified column ID does not exist for this Pulse
400
     * @throws InvalidColumnException  The specified column is not a "person" type column
401
     * @throws InvalidObjectException  The specified column exists but modification of its value is unsupported either
402
     *                                 by this library or the DaPulse API.
403
     *
404
     * @return PulseColumnPersonValue A column object with access to its contents
405
     */
406
    public function getPersonColumn ($columnId)
407
    {
408
        return $this->getColumn($columnId, PulseColumn::Person);
409
    }
410
411
    /**
412
     * Access a text type column value belonging to this pulse in order to read it or modify.
413
     *
414
     * This function should only be used to access text type values; an exception will be thrown otherwise.
415
     *
416
     * @api
417
     *
418
     * @param  string $columnId The ID of the column to access. This is typically a slugified version of the column name
419
     *
420
     * @since  0.1.0
421
422
     * @throws ColumnNotFoundException The specified column ID does not exist for this Pulse
423
     * @throws InvalidColumnException  The specified column is not a "text" type column
424
     * @throws InvalidObjectException  The specified column exists but modification of its value is unsupported either
425
     *                                 by this library or the DaPulse API.
426
     *
427
     * @return PulseColumnTextValue A column object with access to its contents
428
     */
429
    public function getTextColumn ($columnId)
430
    {
431
        return $this->getColumn($columnId, PulseColumn::Text);
432
    }
433
434
    /**
435
     * Build a pulse's column object if it doesn't exist or return the existing column.
436
     *
437
     * @param  string $columnId   The ID of the column to access. This is typically a slugified version of the column
438
     *                            title
439
     * @param  string $columnType The type of column being accessed: 'text', 'color', 'person', 'numeric', or 'date'
440
     *
441
     * @since  0.1.0
442
     *
443
     * @throws ColumnNotFoundException The specified column ID does not exist for this Pulse
444
     * @throws InvalidColumnException  The specified column is not the same type as specified in `$columnType`
445
     * @throws InvalidObjectException  The specified column exists but modification of its value is unsupported either
446
     *                                 by this library or the DaPulse API.
447
     *
448
     * @return PulseColumnValue The returned object will be a child of this abstract class.
449
     */
450
    private function getColumn ($columnId, $columnType)
451
    {
452
        if (!isset($this->column_values) || !array_key_exists($columnId, $this->column_values))
453
        {
454
            $key  = ArrayUtilities::array_search_column($this->raw_column_values, 'cid', $columnId);
455
            $data = array();
456
457
            // We can't find the key, this means that we got our information from accessing a Pulse directly instead of
458
            // getting it through a PulseBoard. This isn't as robust as accessing a PulseBoard but it's more efficient.
459
            // We make a separate API call to get the value of a column.
460
            if ($key === false)
461
            {
462
                $url    = sprintf("%s/%d/columns/%s/value.json", self::apiEndpoint("boards"), $this->getBoardId(), $columnId);
463
                $params = array(
464
                    "pulse_id" => $this->getId()
465
                );
466
467
                try
468
                {
469
                    $results = self::sendGet($url, $params);
470
                }
471
                catch (HttpException $e)
472
                {
473
                    throw new ColumnNotFoundException("The '$columnId' column could not be found");
474
                }
475
476
                // Store our value inside of jsonResponse so all of the respective objects can treat the data the same
477
                // as when accessed through a PulseBoard
478
                $data['jsonResponse']['value'] = $results['value'];
479
            }
480
            else
481
            {
482
                $data = $this->raw_column_values[$key];
483
                $type = $this->column_structure[$key]->getType();
484
485
                if ($type !== $columnType)
486
                {
487
                    throw new InvalidColumnException("The '$columnId' column was expected to be '$columnType' but was '$type' instead.");
488
                }
489
            }
490
491
            $data['column_id'] = $columnId;
492
            $data['board_id']  = $this->getBoardId();
493
            $data['pulse_id']  = $this->getId();
494
495
            $this->column_values[$columnId] = PulseColumnValue::_createColumnType($columnType, $data);
496
        }
497
498
        return $this->column_values[$columnId];
499
    }
500
501
    // ================================================================================================================
502
    //   Notes functions
503
    // ================================================================================================================
504
505
    /**
506
     * Create a new note in this project
507
     *
508
     * @api
509
     *
510
     * @param  string   $title         The title of the note
511
     * @param  string   $content       The body of the note
512
     * @param  bool     $ownersOnly    Set to true if only pulse owners can edit this note.
513
     * @param  int|null $userId        The id of the user to be marked as the note's last updater
514
     * @param  bool     $createUpdate  Indicates whether to create an update on the pulse notifying subscribers on the
515
     *                                 changes (required user_id to be set).
516
     *
517
     * @since  0.1.0
518
     * @return PulseNote
519
     */
520
    public function addNote ($title, $content, $ownersOnly = false, $userId = NULL, $createUpdate = false)
521
    {
522
        $url        = sprintf($this->urlSyntax, self::apiEndpoint(), $this->id, "notes");
523
        $postParams = array(
524
            "id"            => $this->id,
525
            "title"         => $title,
526
            "content"       => $content,
527
            "owners_only"   => $ownersOnly,
528
            "create_update" => $createUpdate
529
        );
530
531
        self::setIfNotNullOrEmpty($postParams, "user_id", $userId);
532
533
        if ($createUpdate && is_null($userId))
534
        {
535
            throw new \InvalidArgumentException("The user_id value must be set if an update is to be created");
536
        }
537
538
        $noteResult = self::sendPost($url, $postParams);
539
540
        return (new PulseNote($noteResult));
541
    }
542
543
    /**
544
     * Return all of the notes belonging to this project
545
     *
546
     * @api
547
     * @since  0.1.0
548
     * @return PulseNote[]
549
     */
550
    public function getNotes ()
551
    {
552
        $url = sprintf($this->urlSyntax, self::apiEndpoint(), $this->id, "notes");
553
554
        return self::fetchAndCastToObjectArray($url, "PulseNote");
555
    }
556
557
    // ================================================================================================================
558
    //   Updates functions
559
    // ================================================================================================================
560
561
    /**
562
     * Get all of the updates that belong this Pulse in reverse chronological order
563
     *
564
     * @api
565
     * @since 0.1.0
566
     * @return PulseUpdate[]
567
     */
568
    public function getUpdates ()
569
    {
570
        $url = sprintf($this->urlSyntax, self::apiEndpoint(), $this->id, "updates");
571
572
        return self::fetchAndCastToObjectArray($url, "PulseUpdate");
573
    }
574
575
    /**
576
     * Create an update for the current Pulse
577
     *
578
     * @api
579
     *
580
     * @param int|PulseUser $user
581
     * @param string        $text
582
     * @param null|bool     $announceToAll
583
     *
584
     * @since 0.1.0
585
     */
586
    public function createUpdate ($user, $text, $announceToAll = NULL)
587
    {
588
        PulseUpdate::createUpdate($user, $this->getId(), $text, $announceToAll);
589
    }
590
591
    // ================================================================================================================
592
    //   Static functions
593
    // ================================================================================================================
594
595
    /**
596
     * Get all of the pulses that belong to the organization across all boards.
597
     *
598
     * To modify the amount of data returned with pagination, use the following values in the array to configure your
599
     * pagination or offsets.
600
     *
601
     * ```php
602
     * $params = array(
603
     *     "page"     => 1,          // (int) Page offset to fetch
604
     *     "per_page" => 10,         // (int) Number of results per page
605
     *     "offset"   => 5,          // (int) Instead of starting at result 0, start counting from result 5
606
     *     "order_by_latest" => true // (bool) Order the pulses with the most recent first
607
     * );
608
     * ```
609
     *
610
     * @api
611
     *
612
     * @param array $params GET parameters passed to with the query to modify the data returned.
613
     *
614
     * @since 0.1.0
615
     * @return Pulse[]
616
     */
617
    public static function getPulses ($params = array())
618
    {
619
        $url = sprintf("%s.json", self::apiEndpoint());
620
621
        return self::fetchAndCastToObjectArray($url, "Pulse", $params);
622
    }
623
}