1<?php
2
3/*
4 * vim:set softtabstop=4 shiftwidth=4 expandtab:
5 *
6 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later)
7 * Copyright 2001 - 2020 Ampache.org
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
21 *
22 */
23
24declare(strict_types=0);
25
26namespace Ampache\Application\Api\Ajax\Handler;
27
28use Ampache\Module\Util\InterfaceImplementationChecker;
29use Ampache\Module\Util\ObjectTypeToClassNameMapper;
30use Ampache\Config\AmpConfig;
31use Ampache\Repository\Model\Browse;
32use Ampache\Module\System\Core;
33use Ampache\Repository\Model\Playlist;
34use Ampache\Repository\Model\Rating;
35use Ampache\Module\Util\Ui;
36use Ampache\Repository\Model\User;
37use Ampache\Repository\Model\Userflag;
38use Ampache\Repository\AlbumRepositoryInterface;
39use Ampache\Repository\SongRepositoryInterface;
40
41final class DefaultAjaxHandler implements AjaxHandlerInterface
42{
43    private AlbumRepositoryInterface $albumRepository;
44
45    private SongRepositoryInterface $songRepository;
46
47    public function __construct(
48        AlbumRepositoryInterface $albumRepository,
49        SongRepositoryInterface $songRepository
50    ) {
51        $this->albumRepository = $albumRepository;
52        $this->songRepository  = $songRepository;
53    }
54
55    public function handle(): void
56    {
57        $results = array();
58
59        // Switch on the actions
60        switch ($_REQUEST['action']) {
61            case 'refresh_rightbar':
62                $results['rightbar'] = Ui::ajax_include('rightbar.inc.php');
63                break;
64            case 'current_playlist':
65                switch ($_REQUEST['type']) {
66                    case 'delete':
67                        Core::get_global('user')->playlist->delete_track($_REQUEST['id']);
68                        break;
69                } // end switch
70
71                $results['rightbar'] = Ui::ajax_include('rightbar.inc.php');
72                break;
73            // Handle the users basketcases...
74            case 'basket':
75                $object_type = $_REQUEST['type'] ?: $_REQUEST['object_type'];
76                $object_id   = $_REQUEST['id'] ?: $_REQUEST['object_id'];
77
78                if (InterfaceImplementationChecker::is_playable_item($object_type)) {
79                    if (!is_array($object_id)) {
80                        $object_id = array($object_id);
81                    }
82                    foreach ($object_id as $item) {
83                        $class_name = ObjectTypeToClassNameMapper::map($object_type);
84                        $object     = new $class_name($item);
85                        $medias     = $object->get_medias();
86                        Core::get_global('user')->playlist->add_medias($medias);
87                    }
88                } else {
89                    switch ($_REQUEST['type']) {
90                        case 'browse_set':
91                        case 'browse_set_random':
92                            $songs   = array();
93                            $browse  = new Browse($_REQUEST['browse_id']);
94                            $objects = $browse->get_saved();
95                            switch ($browse->get_type()) {
96                                case 'album':
97                                    foreach ($objects as $object_id) {
98                                        $songs = array_merge($songs, static::getSongRepository()->getByAlbum($object_id));
99                                    }
100                                    break;
101                                case 'artist':
102                                    foreach ($objects as $object_id) {
103                                        $songs = array_merge($songs, static::getSongRepository()->getAllByArtist($object_id));
104                                    }
105                                    break;
106                                case 'song':
107                                    $songs = $objects;
108                                    break;
109                            } // end switch type
110                            if ($_REQUEST['type'] == 'browse_set_random') {
111                                shuffle($songs);
112                            }
113                            foreach ($songs as $object_id) {
114                                Core::get_global('user')->playlist->add_object($object_id, 'song');
115                            }
116                            break;
117                        case 'album_full':
118                            $songs = $this->albumRepository->getSongsGrouped(explode(',', $_REQUEST['id']));
119                            foreach ($songs as $song_id) {
120                                Core::get_global('user')->playlist->add_object($song_id, 'song');
121                            }
122                            break;
123                        case 'album_random':
124                            $songs = $this->albumRepository->getRandomSongsGrouped(explode(',', $_REQUEST['id']));
125                            foreach ($songs as $song_id) {
126                                Core::get_global('user')->playlist->add_object($song_id, 'song');
127                            }
128                            break;
129                        case 'artist_random':
130                        case 'tag_random':
131                            $data       = explode('_', $_REQUEST['type']);
132                            $type       = $data['0'];
133                            $class_name = ObjectTypeToClassNameMapper::map($type);
134                            $object     = new $class_name($_REQUEST['id']);
135                            $songs      = $this->songRepository->getRandomByArtist($object);
136                            foreach ($songs as $song_id) {
137                                Core::get_global('user')->playlist->add_object($song_id, 'song');
138                            }
139                            break;
140                        case 'playlist_random':
141                            $playlist = new Playlist($_REQUEST['id']);
142                            $items    = $playlist->get_random_items();
143                            foreach ($items as $item) {
144                                Core::get_global('user')->playlist->add_object($item['object_id'], $item['object_type']);
145                            }
146                            break;
147                        case 'clear_all':
148                            Core::get_global('user')->playlist->clear();
149                            break;
150                    }
151                }
152
153                $results['rightbar'] = Ui::ajax_include('rightbar.inc.php');
154                break;
155            /* Setting ratings */
156            case 'set_rating':
157                if (User::is_registered()) {
158                    ob_start();
159                    $rating = new Rating(filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT), Core::get_get('rating_type'));
160                    $rating->set_rating(Core::get_get('rating'));
161                    echo Rating::show(filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT), Core::get_get('rating_type'));
162                    $key           = "rating_" . filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT) . "_" . Core::get_get('rating_type');
163                    $results[$key] = ob_get_contents();
164                    ob_end_clean();
165                } else {
166                    $results['rfc3514'] = '0x1';
167                }
168                break;
169            /* Setting userflags */
170            case 'set_userflag':
171                if (User::is_registered()) {
172                    ob_start();
173                    $flagtype = Core::get_get('userflag_type');
174                    $flag_id  = filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT);
175                    $userflag = new Userflag($flag_id, $flagtype);
176                    $userflag->set_flag($_GET['userflag']);
177                    echo Userflag::show($flag_id, $flagtype);
178                    $key           = "userflag_" . $flag_id . "_" . $flagtype;
179                    $results[$key] = ob_get_contents();
180                    ob_end_clean();
181                } else {
182                    $results['rfc3514'] = '0x1';
183                }
184                break;
185            case 'action_buttons':
186                ob_start();
187                if (AmpConfig::get('ratings')) {
188                    echo " <span id='rating_" . filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT) . "_" . filter_input(INPUT_GET, 'object_type', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES) . "'>";
189                    echo Rating::show(filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT), filter_input(INPUT_GET, 'object_type', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES));
190                    echo "</span>";
191                }
192                if (AmpConfig::get('userflags')) {
193                    echo " <span id='userflag_" . filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT) . "_" . filter_input(INPUT_GET, 'object_type', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES) . "'>";
194                    echo Userflag::show(filter_input(INPUT_GET, 'object_id', FILTER_SANITIZE_NUMBER_INT), filter_input(INPUT_GET, 'object_type', FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES));
195                    echo "</span>";
196                }
197                $results['action_buttons'] = ob_get_contents();
198                ob_end_clean();
199                break;
200            default:
201                $results['rfc3514'] = '0x1';
202                break;
203        } // end switch action
204
205        // Go ahead and do the echo
206        echo (string) xoutput_from_array($results);
207    }
208
209    /**
210     * @deprecated Inject by constructor
211     */
212    private static function getSongRepository(): SongRepositoryInterface
213    {
214        global $dic;
215
216        return $dic->get(SongRepositoryInterface::class);
217    }
218}
219