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\System\Dba;
28use Ampache\Config\AmpConfig;
29use Ampache\Module\System\Core;
30use Ampache\Repository\LabelRepositoryInterface;
31use Ampache\Repository\SongRepositoryInterface;
32use PDOStatement;
33
34/**
35 * This is the class responsible for handling the Label object
36 * it is related to the label table in the database.
37 */
38class Label extends database_object implements library_item
39{
40    protected const DB_TABLENAME = 'label';
41
42    /* Variables from DB */
43
44    /**
45     * @var integer $id
46     */
47    public $id;
48    /**
49     * @var string $name
50     */
51    public $name;
52    /**
53     * @var string $mbid
54     */
55    public $mbid; // MusicBrainz ID
56    /**
57     * @var string $category
58     */
59    public $category;
60    /**
61     * @var string $address
62     */
63    public $address;
64    /**
65     * @var string $email
66     */
67    public $email;
68    /**
69     * @var string $website
70     */
71    public $website;
72    /**
73     * @var string $summary
74     */
75    public $summary;
76    /**
77     * @var string $country
78     */
79    public $country;
80    /**
81     * @var integer $active
82     */
83    public $active;
84    /**
85     * @var integer $user
86     */
87    public $user;
88
89    /**
90     * @var string $f_name
91     */
92    public $f_name;
93    /**
94     * @var string $link
95     */
96    public $link;
97    /**
98     * @var string $f_link
99     */
100    public $f_link;
101    /**
102     * @var integer $artists
103     */
104    public $artists;
105
106    /**
107     * __construct
108     * @param $label_id
109     */
110    public function __construct($label_id)
111    {
112        $info = $this->get_info($label_id);
113
114        foreach ($info as $key => $value) {
115            $this->$key = $value;
116        }
117        $this->active = (int)$this->active;
118
119        return true;
120    }
121
122    public function getId(): int
123    {
124        return (int) $this->id;
125    }
126
127    /**
128     * display_art
129     * @param integer $thumb
130     * @param boolean $force
131     */
132    public function display_art($thumb = 2, $force = false)
133    {
134        if (Art::has_db($this->id, 'label') || $force) {
135            Art::display('label', $this->id, $this->get_fullname(), $thumb, $this->link);
136        }
137    }
138
139    /**
140     * @param boolean $details
141     */
142    public function format($details = true)
143    {
144        unset($details);
145        $this->f_name  = filter_var($this->name, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
146        $this->link    = AmpConfig::get('web_path') . '/labels.php?action=show&label=' . scrub_out($this->id);
147        $this->f_link  = "<a href=\"" . $this->link . "\" title=\"" . scrub_out($this->f_name) . "\">" . scrub_out($this->f_name);
148        $this->artists = count($this->get_artists());
149    }
150
151    /**
152     * @return array|integer[]
153     */
154    public function get_catalogs()
155    {
156        return array();
157    }
158
159    /**
160     * @return array
161     */
162    public function get_childrens()
163    {
164        $medias  = array();
165        $artists = $this->get_artists();
166        foreach ($artists as $artist_id) {
167            $medias[] = array(
168                'object_type' => 'artist',
169                'object_id' => $artist_id
170            );
171        }
172
173        return array('artist' => $medias);
174    }
175
176    /**
177     * @return string
178     */
179    public function get_default_art_kind()
180    {
181        return 'default';
182    }
183
184    /**
185     * @return string
186     */
187    public function get_description()
188    {
189        return $this->summary;
190    }
191
192    /**
193     * @return string
194     */
195    public function get_fullname()
196    {
197        return $this->f_name;
198    }
199
200    /**
201     * get_keywords
202     * @return array
203     */
204    public function get_keywords()
205    {
206        $keywords          = array();
207        $keywords['label'] = array(
208            'important' => true,
209            'label' => T_('Label'),
210            'value' => $this->f_name
211        );
212
213        return $keywords;
214    }
215
216    /**
217     * @param string $filter_type
218     * @return array
219     */
220    public function get_medias($filter_type = null)
221    {
222        $medias = array();
223        if ($filter_type === null || $filter_type == 'song') {
224            $songs = static::getSongRepository()->getByLabel($this->name);
225            foreach ($songs as $song_id) {
226                $medias[] = array(
227                    'object_type' => 'song',
228                    'object_id' => $song_id
229                );
230            }
231        }
232
233        return $medias;
234    }
235
236    /**
237     * @return null
238     */
239    public function get_parent()
240    {
241        return null;
242    }
243
244    /**
245     * @return integer
246     */
247    public function get_user_owner()
248    {
249        return $this->user;
250    }
251
252    /**
253     * search_childrens
254     * @param string $name
255     * @return array
256     */
257    public function search_childrens($name)
258    {
259        $search                    = array();
260        $search['type']            = "artist";
261        $search['rule_0_input']    = $name;
262        $search['rule_0_operator'] = 4;
263        $search['rule_0']          = "title";
264        $artists                   = Search::run($search);
265
266        $childrens = array();
267        foreach ($artists as $artist_id) {
268            $childrens[] = array(
269                'object_type' => 'artist',
270                'object_id' => $artist_id
271            );
272        }
273
274        return $childrens;
275    }
276
277    /**
278     * update
279     * @param array $data
280     * @return integer
281     */
282    public function update(array $data)
283    {
284        if (static::getLabelRepository()->lookup($data['name'], $this->id) !== 0) {
285            return false;
286        }
287
288        $name     = isset($data['name']) ? $data['name'] : $this->name;
289        $mbid     = isset($data['mbid']) ? $data['mbid'] : $this->mbid;
290        $category = isset($data['category']) ? $data['category'] : $this->category;
291        $summary  = isset($data['summary']) ? $data['summary'] : $this->summary;
292        $address  = isset($data['address']) ? $data['address'] : $this->address;
293        $country  = isset($data['country']) ? $data['country'] : $this->country;
294        $email    = isset($data['email']) ? $data['email'] : $this->email;
295        $website  = isset($data['website']) ? $data['website'] : $this->website;
296        $active   = isset($data['active']) ? (int)$data['active'] : $this->active;
297
298        $sql = "UPDATE `label` SET `name` = ?, `mbid` = ?, `category` = ?, `summary` = ?, `address` = ?, `country` = ?, `email` = ?, `website` = ?, `active` = ? WHERE `id` = ?";
299        Dba::write($sql, array($name, $mbid, strtolower($category), $summary, $address, $country, $email, $website, $active, $this->id));
300
301        return $this->id;
302    }
303
304    /**
305     * helper
306     * @param string $name
307     * @return string
308     */
309    public static function helper(string $name)
310    {
311        $label_data = array(
312            'name' => $name,
313            'mbid' => null,
314            'category' => 'tag_generated',
315            'summary' => null,
316            'address' => null,
317            'country' => null,
318            'email' => null,
319            'website' => null,
320            'active' => 1,
321            'user' => 0,
322            'creation_date' => time()
323        );
324
325        return self::create($label_data);
326    }
327
328    /**
329     * create
330     * @param array $data
331     * @return string
332     */
333    public static function create(array $data)
334    {
335        if (static::getLabelRepository()->lookup($data['name']) !== 0) {
336            return false;
337        }
338
339        $name          = $data['name'];
340        $mbid          = $data['mbid'];
341        $category      = $data['category'];
342        $summary       = $data['summary'];
343        $address       = $data['address'];
344        $country       = $data['country'];
345        $email         = $data['email'];
346        $website       = $data['website'];
347        $user          = $data['user'] ?: Core::get_global('user')->id;
348        $active        = $data['active'];
349        $creation_date = $data['creation_date'] ?: time();
350
351        $sql = "INSERT INTO `label` (`name`, `mbid`, `category`, `summary`, `address`, `country`, `email`, `website`, `user`, `active`, `creation_date`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
352        Dba::write($sql, array($name, $mbid, $category, $summary, $address, $country, $email, $website, $user, $active, $creation_date));
353
354        return Dba::insert_id();
355    }
356
357    /**
358     * get_artists
359     * @return integer[]
360     */
361    public function get_artists()
362    {
363        $sql        = "SELECT `artist` FROM `label_asso` WHERE `label` = ?";
364        $db_results = Dba::read($sql, array($this->id));
365        $results    = array();
366        while ($row = Dba::fetch_assoc($db_results)) {
367            $results[] = (int) $row['artist'];
368        }
369
370        return $results;
371    }
372
373    /**
374     * get_display
375     * This returns a csv formatted version of the labels that we are given
376     * @param $labels
377     * @param boolean $link
378     * @return string
379     */
380    public static function get_display($labels, $link = false)
381    {
382        if (!is_array($labels)) {
383            return '';
384        }
385
386        $results = '';
387
388        // Iterate through the labels, format them according to type and element id
389        foreach ($labels as $label_id => $value) {
390            if ($link) {
391                $results .= '<a href="' . AmpConfig::get('web_path') . '/labels.php?action=show&label=' . $label_id . '" title="' . $value . '">';
392            }
393            $results .= $value;
394            if ($link) {
395                $results .= '</a>';
396            }
397            $results .= ', ';
398        }
399
400        $results = rtrim((string)$results, ', ');
401
402        return $results;
403    } // get_display
404
405    /**
406     * Migrate an object associate stats to a new object
407     * @param string $object_type
408     * @param integer $old_object_id
409     * @param integer $new_object_id
410     * @return PDOStatement|boolean
411     */
412    public static function migrate($object_type, $old_object_id, $new_object_id)
413    {
414        if ($object_type == 'artist') {
415            $sql    = "UPDATE `label_asso` SET `artist` = ? WHERE `artist` = ?";
416            $params = array($new_object_id, $old_object_id);
417
418            return Dba::write($sql, $params);
419        }
420
421        return false;
422    }
423
424    /**
425     * garbage_collection
426     *
427     * This cleans out unused artists
428     */
429    public static function garbage_collection()
430    {
431        Dba::write("DELETE FROM `label_asso` WHERE `label_asso`.`artist` NOT IN (SELECT `artist`.`id` FROM `artist`);");
432    }
433
434    private static function getLabelRepository(): LabelRepositoryInterface
435    {
436        global $dic;
437
438        return $dic->get(LabelRepositoryInterface::class);
439    }
440
441    private static function getSongRepository(): SongRepositoryInterface
442    {
443        global $dic;
444
445        return $dic->get(SongRepositoryInterface::class);
446    }
447}
448