Completed
Push — master ( 39f807...391e9b )
by Vladimir
03:25
created

Pulse::getNotes()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 0
loc 6
rs 9.4286
cc 1
eloc 3
nc 1
nop 0
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\HttpException;
13
use allejo\DaPulse\Exceptions\InvalidColumnException;
14
use allejo\DaPulse\Exceptions\InvalidObjectException;
15
use allejo\DaPulse\Objects\PulseColumnDateValue;
16
use allejo\DaPulse\Objects\PulseColumnPersonValue;
17
use allejo\DaPulse\Objects\PulseColumnStatusValue;
18
use allejo\DaPulse\Objects\PulseColumnTextValue;
19
use allejo\DaPulse\Objects\PulseColumnValue;
20
use allejo\DaPulse\Objects\SubscribableObject;
21
use allejo\DaPulse\Utilities\ArrayUtilities;
22
23
/**
24
 * A class representing a single pulse in a board
25
 *
26
 * @api
27
 * @package allejo\DaPulse
28
 * @since   0.1.0
29
 */
30
class Pulse extends SubscribableObject
31
{
32
    /**
33
     * @ignore
34
     */
35
    const API_PREFIX = "pulses";
36
37
    // ================================================================================================================
38
    //   Instance Variables
39
    // ================================================================================================================
40
41
    /**
42
     * The resource's URL.
43
     *
44
     * @var string
45
     */
46
    protected $url;
47
48
    /**
49
     * The pulse's name.
50
     *
51
     * @var string
52
     */
53
    protected $name;
54
55
    /**
56
     * The board's subscribers.
57
     *
58
     * @var PulseUser[]
59
     */
60
    protected $subscribers;
61
62
    /**
63
     * The amount of updates a pulse has.
64
     *
65
     * @var int
66
     */
67
    protected $updates_count;
68
69
    /**
70
     * The ID of the parent board.
71
     *
72
     * @var int
73
     */
74
    protected $board_id;
75
76
    /**
77
     * Creation time.
78
     *
79
     * @var \DateTime
80
     */
81
    protected $created_at;
82
83
    /**
84
     * Last update time.
85
     *
86
     * @var \DateTime
87
     */
88
    protected $updated_at;
89
90
    /**
91
     * The ID of the group this pulse belongs to
92
     *
93
     * @var string
94
     */
95
    protected $group_id;
96
97
    /**
98
     * @var PulseColumn[]
99
     */
100
    protected $column_structure;
101
102
    /**
103
     * An array containing all of the values a pulse has for each column
104
     *
105
     * @var mixed
106
     */
107
    protected $raw_column_values;
108
109
    /**
110
     * An array containing objects extended from PulseColumnValue storing all of the values for each column
111
     *
112
     * @var array
113
     */
114
    protected $column_values;
115
116
    /**
117
     * The common URL path for retrieving objects relating a pulse such as subscribers, notes, or updates
118
     *
119
     * @var string
120
     */
121
    private $urlSyntax = "%s/%s/%s.json";
122
123
    // ================================================================================================================
124
    //   Overloaded functions
125
    // ================================================================================================================
126
127
    protected function initializeValues ()
128
    {
129
        $this->column_values     = array();
130
        $this->column_structure  = array();
131
        $this->raw_column_values = array();
132
    }
133
134
    // ================================================================================================================
135
    //   Getter functions
136
    // ================================================================================================================
137
138
    /**
139
     * The resource's URL.
140
     *
141
     * @return string
142
     */
143
    public function getUrl ()
144
    {
145
        return $this->url;
146
    }
147
148
    /**
149
     * The pulse's name.
150
     *
151
     * @return string
152
     */
153
    public function getName ()
154
    {
155
        return $this->name;
156
    }
157
158
    /**
159
     * The amount of updates a pulse has.
160
     *
161
     * @return int
162
     */
163
    public function getUpdatesCount ()
164
    {
165
        return $this->updates_count;
166
    }
167
168
    /**
169
     * The ID of the parent board.
170
     *
171
     * @return int
172
     */
173
    public function getBoardId ()
174
    {
175
        return $this->board_id;
176
    }
177
178
    /**
179
     * Creation time.
180
     *
181
     * @return \DateTime
182
     */
183
    public function getCreatedAt ()
184
    {
185
        self::lazyLoad($this->created_at, '\DateTime');
186
187
        return $this->created_at;
188
    }
189
190
    /**
191
     * Last update time.
192
     *
193
     * @return \DateTime
194
     */
195
    public function getUpdatedAt ()
196
    {
197
        self::lazyLoad($this->updated_at, '\DateTime');
198
199
        return $this->updated_at;
200
    }
201
202
    /**
203
     * 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
204
     * find the group ID via brute force.
205
     *
206
     * **Note** The group ID is cached if it is not available. To update the cached value, use $forceFetch to force an
207
     * API call to get a new value.
208
     *
209
     * **Warning** An API call is always slower than using the cached value.
210
     *
211
     * @param bool $forceFetch Force an API call to get an updated group ID if it has been changed
212
     *
213
     * @since 0.1.0
214
     * @return string
215
     */
216
    public function getGroupId ($forceFetch = false)
217
    {
218
        if (empty($this->group_id) || $forceFetch)
219
        {
220
            $parentBoard = new PulseBoard($this->board_id);
221
            $pulses      = $parentBoard->getPulses();
222
223
            foreach ($pulses as $pulse)
224
            {
225
                if ($this->getId() === $pulse->getId())
226
                {
227
                    $this->group_id = $pulse->getGroupId();
228
                    break;
229
                }
230
            }
231
        }
232
233
        return $this->group_id;
234
    }
235
236
    // ================================================================================================================
237
    //   Pulse functions
238
    // ================================================================================================================
239
240
    /**
241
     * Delete the current Pulse
242
     *
243
     * @api
244
     * @throws \allejo\DaPulse\Exceptions\InvalidObjectException
245
     */
246 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...
247
    {
248
        $this->checkInvalid();
249
250
        $deleteURL = sprintf("%s/%d.json", self::apiEndpoint(), $this->getId());
251
252
        self::sendDelete($deleteURL);
253
254
        $this->deletedObject = true;
255
    }
256
257
    public function duplicatePulse ($groupId = NULL, $ownerId = NULL)
258
    {
259
        $url        = sprintf("%s/%s/pulses/%s/duplicate.json", self::apiEndpoint("boards"), $this->getBoardId(), $this->getId());
260
        $postParams = array();
261
262
        if ($ownerId instanceof PulseUser)
263
        {
264
            $ownerId = $ownerId->getId();
265
        }
266
267
        self::setIfNotNullOrEmpty($postParams, "group_id", $groupId);
268
        self::setIfNotNullOrEmpty($postParams, "owner_id", $ownerId);
269
270
        $result = self::sendPost($url, $postParams);
271
        $this->pulseInjection($result);
272
273
        return (new Pulse($result['pulse']));
274
    }
275
276 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...
277
    {
278
        $parentBoard = new PulseBoard($this->getBoardId());
279
280
        // Inject some information so a Pulse object can survive on its own
281
        $result["pulse"]["group_id"]          = $result["board_meta"]["group_id"];
282
        $result["pulse"]["column_structure"]  = $parentBoard->getColumns();
283
        $result["pulse"]["raw_column_values"] = $result["column_values"];
284
    }
285
286
    // ================================================================================================================
287
    //   Column data functions
288
    // ================================================================================================================
289
290
    /**
291
     * Access a pulse's specific column to either access their value or to modify the value.
292
     *
293
     * See the related functions to see the appropriate replacements.
294
     *
295
     * @todo       This function only exists for legacy applications. Remove in 0.1.1
0 ignored issues
show
Coding Style introduced by
Comment refers to a TODO task

This check looks TODO comments that have been left in the code.

``TODO``s show that something is left unfinished and should be attended to.

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