1<?php
2/*
3 * vim:set softtabstop=4 shiftwidth=4 expandtab:
4 *
5 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later)
6 * Copyright 2001 - 2020 Ampache.org
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20 *
21 */
22
23declare(strict_types=0);
24
25namespace Ampache\Repository\Model;
26
27use Ampache\Module\Util\Ui;
28use Ampache\Module\Api\Ajax;
29use Ampache\Config\AmpConfig;
30use Ampache\Module\System\Core;
31use Ampache\Module\System\Dba;
32use PDOStatement;
33
34class Broadcast extends database_object implements library_item
35{
36    protected const DB_TABLENAME = 'broadcast';
37
38    /**
39     * @var integer $id
40     */
41    public $id;
42    /**
43     * @var boolean $started
44     */
45    public $started;
46    /**
47     * @var integer $listeners
48     */
49    public $listeners;
50    /**
51     * @var integer $song
52     */
53    public $song;
54    /**
55     * @var integer $song_position
56     */
57    public $song_position;
58    /**
59     * @var string $name
60     */
61    public $name;
62    /**
63     * @var integer $user
64     */
65    public $user;
66
67    /**
68     * @var array $tags
69     */
70    public $tags;
71    /**
72     * @var string $f_name
73     */
74    public $f_name;
75    /**
76     * @var string $f_link
77     */
78    public $f_link;
79    /**
80     * @var string $f_tags
81     */
82    public $f_tags;
83    /**
84     * @var boolean $is_private
85     */
86    public $is_private;
87
88    /**
89     * Constructor
90     * @param integer $broadcast_id
91     */
92    public function __construct($broadcast_id)
93    {
94        /* Get the information from the db */
95        $info = $this->get_info($broadcast_id);
96
97        // Foreach what we've got
98        foreach ($info as $key => $value) {
99            $this->$key = $value;
100        }
101
102        return true;
103    } // constructor
104
105    public function getId(): int
106    {
107        return (int) $this->id;
108    }
109
110    /**
111     * Update broadcast state.
112     * @param boolean $started
113     * @param string $key
114     */
115    public function update_state($started, $key = '')
116    {
117        $sql = "UPDATE `broadcast` SET `started` = ?, `key` = ?, `song` = '0', `listeners` = '0' WHERE `id` = ?";
118        Dba::write($sql, array($started, $key, $this->id));
119
120        $this->started = $started;
121    }
122
123    /**
124     * Update broadcast listeners.
125     * @param integer $listeners
126     */
127    public function update_listeners($listeners)
128    {
129        $sql = "UPDATE `broadcast` SET `listeners` = ? WHERE `id` = ?";
130        Dba::write($sql, array($listeners, $this->id));
131        $this->listeners = $listeners;
132    }
133
134    /**
135     * Update broadcast current song.
136     * @param integer $song_id
137     */
138    public function update_song($song_id)
139    {
140        $sql = "UPDATE `broadcast` SET `song` = ? WHERE `id` = ?";
141        Dba::write($sql, array($song_id, $this->id));
142        $this->song          = $song_id;
143        $this->song_position = 0;
144    }
145
146    /**
147     * Delete the broadcast.
148     * @return PDOStatement|boolean
149     */
150    public function delete()
151    {
152        $sql = "DELETE FROM `broadcast` WHERE `id` = ?";
153
154        return Dba::write($sql, array($this->id));
155    }
156
157    /**
158     * Create a broadcast
159     * @param string $name
160     * @param string $description
161     * @return integer
162     */
163    public static function create($name, $description = '')
164    {
165        if (!empty($name)) {
166            $sql    = "INSERT INTO `broadcast` (`user`, `name`, `description`, `is_private`) VALUES (?, ?, ?, '1')";
167            $params = array(Core::get_global('user')->id, $name, $description);
168            Dba::write($sql, $params);
169
170            return Dba::insert_id();
171        }
172
173        return 0;
174    }
175
176    /**
177     * Update a broadcast from data array.
178     * @param array $data
179     * @return integer
180     */
181    public function update(array $data)
182    {
183        if (isset($data['edit_tags'])) {
184            Tag::update_tag_list($data['edit_tags'], 'broadcast', $this->id, true);
185        }
186
187        $sql    = "UPDATE `broadcast` SET `name` = ?, `description` = ?, `is_private` = ? WHERE `id` = ?";
188        $params = array($data['name'], $data['description'], !empty($data['private']), $this->id);
189        Dba::write($sql, $params);
190
191        return $this->id;
192    }
193
194    /**
195     * @param boolean $details
196     */
197    public function format($details = true)
198    {
199        $this->f_name = filter_var($this->name, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
200        $this->f_link = '<a href="' . AmpConfig::get('web_path') . '/broadcast.php?id=' . $this->id . '">' . $this->f_name . '</a>';
201        if ($details) {
202            $this->tags   = Tag::get_top_tags('broadcast', $this->id);
203            $this->f_tags = Tag::get_display($this->tags, true, 'broadcast');
204        }
205    }
206
207    /**
208     * Get item keywords for metadata searches.
209     * @return array
210     */
211    public function get_keywords()
212    {
213        return array();
214    }
215
216    /**
217     * Get item fullname.
218     * @return string
219     */
220    public function get_fullname()
221    {
222        return $this->f_name;
223    }
224
225    /**
226     * Get parent item description.
227     * @return array|null
228     */
229    public function get_parent()
230    {
231        return null;
232    }
233
234    /**
235     * Get item childrens.
236     * @return array
237     */
238    public function get_childrens()
239    {
240        return array();
241    }
242
243    /**
244     * Search for item childrens.
245     * @param string $name
246     * @return array
247     */
248    public function search_childrens($name)
249    {
250        debug_event(self::class, 'search_childrens ' . $name, 5);
251
252        return array();
253    }
254
255    /**
256     * Get all childrens and sub-childrens medias.
257     * @param string $filter_type
258     * @return array
259     */
260    public function get_medias($filter_type = null)
261    {
262        // Not a media, shouldn't be that
263        $medias = array();
264        if ($filter_type === null || $filter_type == 'broadcast') {
265            $medias[] = array(
266                'object_type' => 'broadcast',
267                'object_id' => $this->id
268            );
269        }
270
271        return $medias;
272    }
273
274    /**
275     * get_catalogs
276     *
277     * Get all catalog ids related to this item.
278     * @return integer[]
279     */
280    public function get_catalogs()
281    {
282        return array();
283    }
284
285    /**
286     * Get item's owner.
287     * @return integer|null
288     */
289    public function get_user_owner()
290    {
291        return $this->user;
292    }
293
294    /**
295     * Get default art kind for this item.
296     * @return string
297     */
298    public function get_default_art_kind()
299    {
300        return 'default';
301    }
302
303    /**
304     * @return mixed|null
305     */
306    public function get_description()
307    {
308        return null;
309    }
310
311    /**
312     * display_art
313     * @param integer $thumb
314     * @param boolean $force
315     */
316    public function display_art($thumb = 2, $force = false)
317    {
318        if (Art::has_db($this->id, 'broadcast') || $force) {
319            Art::display('broadcast', $this->id, $this->get_fullname(), $thumb);
320        }
321    }
322
323    /**
324     * Generate a new broadcast key.
325     * @return string
326     */
327    public static function generate_key()
328    {
329        // Should be improved for security reasons!
330        return md5(uniqid((string)rand(), true));
331    }
332
333    /**
334     * Get broadcast from its key.
335     * @param string $key
336     * @return Broadcast|null
337     */
338    public static function get_broadcast($key)
339    {
340        $sql        = "SELECT `id` FROM `broadcast` WHERE `key` = ?";
341        $db_results = Dba::read($sql, array($key));
342
343        if ($results = Dba::fetch_assoc($db_results)) {
344            return new Broadcast($results['id']);
345        }
346
347        return null;
348    }
349
350    /**
351     * Show action buttons.
352     */
353    public function show_action_buttons()
354    {
355        if ($this->id) {
356            if (Core::get_global('user')->has_access('75')) {
357                echo "<a id=\"edit_broadcast_ " . $this->id . "\" onclick=\"showEditDialog('broadcast_row', '" . $this->id . "', 'edit_broadcast_" . $this->id . "', '" . T_('Broadcast Edit') . "', 'broadcast_row_')\">" . Ui::get_icon('edit',
358                        T_('Edit')) . "</a>";
359                echo " <a href=\"" . AmpConfig::get('web_path') . "/broadcast.php?action=show_delete&id=" . $this->id . "\">" . Ui::get_icon('delete',
360                        T_('Delete')) . "</a>";
361            }
362        }
363    }
364
365    /**
366     * Get broadcast link.
367     * @return string
368     */
369    public static function get_broadcast_link()
370    {
371        $link = "<div class=\"broadcast-action\">";
372        $link .= "<a href=\"#\" onclick=\"showBroadcastsDialog(event);\">" . Ui::get_icon('broadcast',
373                T_('Broadcast')) . "</a>";
374        $link .= "</div>";
375
376        return $link;
377    }
378
379    /**
380     * Get unbroadcast link.
381     * @param integer $broadcast_id
382     * @return string
383     */
384    public static function get_unbroadcast_link($broadcast_id)
385    {
386        $link = "<div class=\"broadcast-action\">";
387        $link .= Ajax::button('?page=player&action=unbroadcast&broadcast_id=' . $broadcast_id, 'broadcast',
388            T_('Unbroadcast'), 'broadcast_action');
389        $link .= "</div>";
390        $link .= "<div class=\"broadcast-info\">(<span id=\"broadcast_listeners\">0</span>)</div>";
391
392        return $link;
393    }
394
395    /**
396     * Get broadcasts from an user.
397     * @param integer $user_id
398     * @return integer[]
399     */
400    public static function get_broadcasts($user_id)
401    {
402        $sql        = "SELECT `id` FROM `broadcast` WHERE `user` = ?";
403        $db_results = Dba::read($sql, array($user_id));
404
405        $broadcasts = array();
406        while ($results = Dba::fetch_assoc($db_results)) {
407            $broadcasts[] = (int)$results['id'];
408        }
409
410        return $broadcasts;
411    }
412
413    /**
414     * Get play url.
415     *
416     * @param string $additional_params
417     * @param string $player
418     * @param boolean $local
419     * @return integer
420     */
421    public function play_url($additional_params = '', $player = null, $local = false)
422    {
423        unset($additional_params, $player, $local);
424
425        return $this->id;
426    }
427}
428