• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mixerapi / mixerapi-dev / 13002105632

28 Jan 2025 01:57AM UTC coverage: 86.907% (-0.5%) from 87.451%
13002105632

Pull #156

github

web-flow
Merge 9f35307d0 into 9d91f041b
Pull Request #156: Adds beforeSerialize and afterSerialize events

24 of 33 new or added lines in 3 files covered. (72.73%)

6 existing lines in 2 files now uncovered.

916 of 1054 relevant lines covered (86.91%)

3.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.0
/plugins/collection-view/src/Serializer.php
1
<?php
2
declare(strict_types=1);
3

4
namespace MixerApi\CollectionView;
5

6
use Adbar\Dot;
7
use Cake\Core\Configure;
8
use Cake\Datasource\Paging\PaginatedResultSet;
9
use Cake\Datasource\ResultSetInterface;
10
use Cake\Event\Event;
11
use Cake\Event\EventManager;
12
use Cake\Http\ServerRequest;
13
use Cake\Utility\Xml;
14
use Cake\View\Helper\PaginatorHelper;
15
use RuntimeException;
16

17
/**
18
 * Serializes the CollectionView into either JSON or XML.
19
 */
20
class Serializer
21
{
22
    public const BEFORE_SERIALIZE_EVENT = 'MixerApi.CollectionView.beforeSerialize';
23
    public const AFTER_SERIALIZE_EVENT = 'MixerApi.CollectionView.afterSerialize';
24

25
    /**
26
     * serialized data
27
     *
28
     * @var array
29
     */
30
    private mixed $data;
31

32
    /**
33
     * @var array
34
     */
35
    private array $config;
36

37
    /**
38
     * If constructed without parameters collection meta data will not be added to HAL $data
39
     *
40
     * @param mixed $serialize the data to be converted into a HAL array
41
     * @param \Cake\Http\ServerRequest|null $request optional ServerRequest
42
     * @param \Cake\View\Helper\PaginatorHelper|null $paginator optional PaginatorHelper
43
     */
44
    public function __construct(
45
        mixed $serialize,
46
        private ?ServerRequest $request = null,
47
        private ?PaginatorHelper $paginator = null
48
    )
49
    {
50
        $this->config = Configure::read('CollectionView');
5✔
51

52
        if ($serialize instanceof ResultSetInterface || $serialize instanceof PaginatedResultSet) {
5✔
53
            $this->data = $this->collection($serialize);
4✔
54
        } else {
55
            $this->data = $serialize;
1✔
56
        }
57
    }
58

59
    /**
60
     * Serializes as JSON
61
     *
62
     * @param int $jsonOptions JSON options see https://www.php.net/manual/en/function.json-encode.php
63
     * @return string
64
     * @throws \RuntimeException
65
     */
66
    public function asJson(int $jsonOptions = 0): string
67
    {
68
        EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this, [
3✔
69
            'type' => 'json',
3✔
70
        ]));
3✔
71

72
        $json = json_encode($this->data, $jsonOptions);
3✔
73

74
        if ($json === false) {
3✔
75
            throw new RuntimeException(json_last_error_msg(), json_last_error());
1✔
76
        }
77

78
        EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [
2✔
79
            'type' => 'json',
2✔
80
            'data' => $json,
2✔
81
        ]));
2✔
82

83
        return $json;
2✔
84
    }
85

86
    /**
87
     * Serializes as XML
88
     *
89
     * @param array $options same as Cake\Utility\Xml
90
     * @param string $rootNode the rootNode
91
     * @return string
92
     * @throws \RuntimeException
93
     */
94
    public function asXml(array $options, string $rootNode = 'response'): string
95
    {
96
        EventManager::instance()->dispatch(new Event(self::BEFORE_SERIALIZE_EVENT, $this, [
2✔
97
            'type' => 'xml',
2✔
98
        ]));
2✔
99

100
        $xml = Xml::fromArray([$rootNode => $this->data], $options)->saveXML();
2✔
101

102
        EventManager::instance()->dispatch(new Event(self::AFTER_SERIALIZE_EVENT, $this, [
2✔
103
            'type' => 'xml',
2✔
104
            'data' => $xml,
2✔
105
        ]));
2✔
106

107
        return $xml;
2✔
108
    }
109

110
    /**
111
     * @return mixed
112
     */
113
    public function getData(): mixed
114
    {
115
        return $this->data;
1✔
116
    }
117

118
    public function setData(mixed $data): void
119
    {
NEW
120
        $this->data = $data;
×
121
    }
122

123
    /**
124
     * @return \Cake\Http\ServerRequest|null
125
     */
126
    public function getRequest(): ?ServerRequest
127
    {
NEW
128
        return $this->request;
×
129
    }
130

131
    /**
132
     * @return \Cake\View\Helper\PaginatorHelper|null
133
     */
134
    public function getPaginatorHelper(): ?PaginatorHelper
135
    {
NEW
136
        return $this->paginator;
×
137
    }
138

139
    /**
140
     * @param \Cake\Datasource\ResultSetInterface|\Cake\Datasource\Paging\PaginatedResultSet $resultSet the data to be converted into a HAL array
141
     * @return array
142
     */
143
    private function collection(mixed $resultSet): array
144
    {
145
        $dot = new Dot();
4✔
146
        foreach ($this->config as $key => $value) {
4✔
147
            $dot->set($key, $value);
4✔
148
        }
149

150
        $return = $dot->all();
4✔
151

152
        $collection = array_search('{{collection}}', $this->config);
4✔
153
        $url = array_search('{{url}}', $return[$collection]);
4✔
154
        $count = array_search('{{count}}', $return[$collection]);
4✔
155
        $pages = array_search('{{pages}}', $return[$collection]);
4✔
156
        $total = array_search('{{total}}', $return[$collection]);
4✔
157
        $next = array_search('{{next}}', $return[$collection]);
4✔
158
        $prev = array_search('{{prev}}', $return[$collection]);
4✔
159
        $first = array_search('{{first}}', $return[$collection]);
4✔
160
        $last = array_search('{{last}}', $return[$collection]);
4✔
161
        $data = array_search('{{data}}', $this->config);
4✔
162

163
        $return[$collection][$count] = intval($resultSet->count());
4✔
164
        $return[$collection][$url] = '';
4✔
165

166
        if ($this->request instanceof ServerRequest) {
4✔
167
            $uri = $this->request->getUri();
4✔
168
            $query = $uri->getQuery();
4✔
169
            $return[$collection][$url] = $uri->getPath();
4✔
170
            $return[$collection][$url] .= !empty($query) ? '?' . $query : '';
4✔
171
        }
172

173
        if ($this->paginator instanceof PaginatorHelper) {
4✔
174
            $return[$collection][$next] = $this->paginator->next();
4✔
175
            $return[$collection][$prev] = $this->paginator->prev();
4✔
176
            $return[$collection][$first] = $this->paginator->first();
4✔
177
            $return[$collection][$last] = $this->paginator->last();
4✔
178
            $return[$collection][$pages] = $this->paginator->total();
4✔
179
            $return[$collection][$total] = intval($this->paginator->param('totalCount'));
4✔
180
        }
181

182
        if (empty($return[$collection][$first]) && !empty($return[$collection][$url])) {
4✔
183
            $return[$collection][$first] = $return[$collection][$url];
4✔
184
        }
185

186
        $return[$data] = $resultSet->toArray();
4✔
187

188
        return $return;
4✔
189
    }
190
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc