SpotifyWebApi::getUserPlaylistByName()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 11
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 2
1
<?php declare(strict_types=1);
2
3
namespace SpotifyApiConnect\Application\SpotifyWebApiPhp;
4
5
use SpotifyApiConnect\Domain\DataTransferObject\DeleteTrackInfoDataProvider;
6
use SpotifyApiConnect\Domain\DataTransferObject\PlaylistDataProvider;
7
use SpotifyApiConnect\Domain\DataTransferObject\PlaylistTracksDataProvider;
8
use SpotifyApiConnect\Domain\DataTransferObject\TrackSearchRequestDataProvider;
9
use SpotifyApiConnect\Domain\DataTransferObject\TracksSearchDataProvider;
10
use SpotifyApiConnect\Domain\DataTransferObject\UserPlaylistsDataProvider;
11
use SpotifyApiConnect\Domain\Exception\PlaylistNotFound;
12
use SpotifyApiConnect\Domain\Model\ConfigInterface;
13
use SpotifyApiConnect\Message;
14
use SpotifyApiConnect\Application\SpotifyWebApiInterface;
15
use SpotifyWebAPI\SpotifyWebAPI as BaseSpotifyWebAPI;
16
use SpotifyWebAPI\Request;
17
use RuntimeException;
18
19
class SpotifyWebApi implements SpotifyWebApiInterface
20
{
21
    private const ID_TO_TRACK_URI = 'spotify:track:%s';
22
23
    /**
24
     * @var BaseSpotifyWebAPI
25
     */
26
    private $baseSpotifyWebAPI;
27
28
    /**
29
     * @var string
30
     */
31
    private $spotifyUsername;
32
33
    /**
34
     * @param string $accessToken
35
     * @param ConfigInterface $config
36
     */
37
    public function __construct(
38
        string $accessToken,
39
        ConfigInterface $config
40
    )
41
    {
42
        $this->baseSpotifyWebAPI = new BaseSpotifyWebAPI();
43
        $this->baseSpotifyWebAPI->setAccessToken($accessToken);
44
        $this->baseSpotifyWebAPI->setReturnType(Request::RETURN_ASSOC);
45
46
        $this->spotifyUsername = $config->getSpotifyUsername();
47
    }
48
49
    /**
50
     * @param $playlistId
51
     * @param array $tracks
52
     * @param array $options
53
     * @return bool
54
     */
55
    public function addPlaylistTracks($playlistId, array $tracks, array $options = []): bool
56
    {
57
        $trackIds = [];
58
        $returnAddPlaylistResult = false;
59
        foreach ($tracks as $trackId) {
60
            $trackIds[] = $trackId;
61
            if (count($trackIds) % 100 === 0) {
62
                $returnAddPlaylistResult = $this->baseSpotifyWebAPI->addPlaylistTracks($playlistId, $trackIds, $options);
63
                $trackIds = [];
64
            }
65
        }
66
67
        if (!empty($trackIds)) {
68
            $returnAddPlaylistResult = $this->baseSpotifyWebAPI->addPlaylistTracks($playlistId, $trackIds, $options);
69
        }
70
71
        return $returnAddPlaylistResult;
72
    }
73
74
    /**
75
     * @param string $playlistId
76
     * @param DeleteTrackInfoDataProvider[] $tracksInfo
77
     * @return bool
78
     */
79
    public function deletePlaylistTracks(string $playlistId, array $tracksInfo): bool
80
    {
81
        $tracksToDelete = [];
82
        $delete = false;
83
        $this->baseSpotifyWebAPI->setReturnType(Request::RETURN_OBJECT);
84
85
        foreach ($tracksInfo as $deleteTrackInfoDataProvider) {
86
            if (!$deleteTrackInfoDataProvider instanceof DeleteTrackInfoDataProvider) {
87
                throw new RuntimeException(
88
                    sprintf(Message::ERROR_DELETE_PLAYLIST_TRACKS, DeleteTrackInfoDataProvider::class)
89
                );
90
            }
91
            $tracksToDelete[] = $deleteTrackInfoDataProvider->toArray();
92
            if (count($tracksToDelete) % 100 === 0) {
93
                $delete = (bool)$this->baseSpotifyWebAPI->deletePlaylistTracks($playlistId, ['tracks' => $tracksToDelete]);
94
                $tracksToDelete = [];
95
            }
96
        }
97
98
        if(!empty($tracksToDelete)) {
99
            $delete = (bool)$this->baseSpotifyWebAPI->deletePlaylistTracks($playlistId, ['tracks' => $tracksToDelete]);
100
        }
101
102
        $this->baseSpotifyWebAPI->setReturnType(Request::RETURN_ASSOC);
103
104
        return $delete;
105
    }
106
107
    /**
108
     * @param string $playlistId
109
     * @param array $options
110
     * @return PlaylistDataProvider
111
     */
112
    public function getPlaylist(string $playlistId, array $options = []): PlaylistDataProvider
113
    {
114
        $jsonObjectResult = (array)$this->baseSpotifyWebAPI->getPlaylist($playlistId, $options);
115
116
        $playlistDataProvider = new PlaylistDataProvider();
117
        $playlistDataProvider->fromArray($jsonObjectResult);
118
119
        return $playlistDataProvider;
120
    }
121
122
    /**
123
     * @param string $playlistName
124
     * @param array $options
125
     * @return PlaylistDataProvider
126
     * @throws PlaylistNotFound
127
     */
128
    public function getUserPlaylistByName(string $playlistName, array $options = []): PlaylistDataProvider
129
    {
130
        $userPlaylistsDataProvider = $this->getUserPlaylists($options);
131
        $playlists = $userPlaylistsDataProvider->getItems();
132
        foreach ($playlists as $playlist) {
133
            if (trim($playlist->getName()) === trim($playlistName)) {
134
                return $playlist;
135
            }
136
        }
137
138
        throw new PlaylistNotFound(sprintf(Message::ERROR_GET_USER_PLAYLIST_BY_NAME, $playlistName));
139
    }
140
141
    /**
142
     * @param string $playlistId
143
     * @param array $options
144
     * @return PlaylistTracksDataProvider
145
     */
146
    public function getPlaylistTracks(string $playlistId, array $options = []): PlaylistTracksDataProvider
147
    {
148
        $offset = 0;
149
        $items = [];
150
151
        do {
152
            $response = (object)$this->baseSpotifyWebAPI->getPlaylistTracks($playlistId, [
153
                'offset' => $offset,
154
            ]);
155
            $offset += 100;
156
            $items[] = $response->items;
157
            $hasNext = $response->next;
158
        } while ($hasNext);
159
        $response->items = array_merge([], ...$items);
160
161
        $playlistTracksDataProvider = new PlaylistTracksDataProvider();
162
        $playlistTracksDataProvider->fromArray((array)$response);
163
164
        return $playlistTracksDataProvider;
165
    }
166
167
    /**
168
     * @param TrackSearchRequestDataProvider $trackSearchRequest
169
     * @param array $options
170
     * @return TracksSearchDataProvider
171
     */
172
    public function searchTrack(TrackSearchRequestDataProvider $trackSearchRequest, array $options = []): TracksSearchDataProvider
173
    {
174
        $jsonObjectResult = $this->search(
175
            sprintf(
176
                Message::SEARCH_TRACK,
177
                $trackSearchRequest->getTrack(),
178
                $trackSearchRequest->getArtist()
179
            ), [
180
            $trackSearchRequest->getType()
181
        ],
182
            $options
183
        );
184
185
        $tracksSearchDataProvider = new TracksSearchDataProvider();
186
        $tracksSearchDataProvider->fromArray($jsonObjectResult[$trackSearchRequest->getResultType()]);
187
188
        return $tracksSearchDataProvider;
189
    }
190
191
    /**
192
     * @param string $query
193
     * @param array $type
194
     * @param array $options
195
     * @return array
196
     */
197
    private function search(string $query, array $type, array $options = []): array
198
    {
199
        return (array)$this->baseSpotifyWebAPI->search($query, $type, $options);
200
    }
201
202
    /**
203
     * @param array $options
204
     * @return UserPlaylistsDataProvider
205
     */
206
    private function getUserPlaylists(array $options = []): UserPlaylistsDataProvider
207
    {
208
        $userPlaylistInfo = (array)$this->baseSpotifyWebAPI->getUserPlaylists($this->spotifyUsername, $options);
209
210
        $userPlaylistsDataProvider = new UserPlaylistsDataProvider();
211
        $userPlaylistsDataProvider->fromArray($userPlaylistInfo);
212
213
        return $userPlaylistsDataProvider;
214
    }
215
}