/** * parse * * Takes an url and parses out all the chewy goodness. */ public static function parse($url) { if (AmpConfig::get('stream_beautiful_url')) { $posargs = strpos($url, '/play/'); if ($posargs !== false) { $argsstr = substr($url, $posargs + 6); $url = substr($url, 0, $posargs + 6) . 'index.php?'; $args = explode('/', $argsstr); for ($i = 0; $i < count($args); $i += 2) { if ($i > 0) { $url .= '&'; } $url .= $args[$i] . '=' . $args[$i + 1]; } } } $query = parse_url($url, PHP_URL_QUERY); $elements = explode('&', $query); $results = array(); $results['base_url'] = $url; foreach ($elements as $element) { list($key, $value) = explode('=', $element); switch ($key) { case 'oid': $key = 'id'; break; case 'video': if (make_bool($value)) { $results['type'] = 'video'; } default: // Nothing break; } $results[$key] = $value; } return $results; }
if (isset($_REQUEST['subtitle'])) { $subtitle = $media->get_subtitle_file($_REQUEST['subtitle']); } $media->format(); } } if (!User::stream_control(array(array('object_type' => $type, 'object_id' => $media->id)))) { debug_event('UI::access_denied', 'Stream control failed for user ' . $GLOBALS['user']->username . ' on ' . $media->get_stream_name(), 3); UI::access_denied(); exit; } if ($media->catalog) { // Build up the catalog for our current object $catalog = Catalog::create_from_id($media->catalog); /* If the media is disabled */ if (!make_bool($media->enabled)) { debug_event('Play', "Error: {$media->file} is currently disabled, song skipped", '5'); // Check to see if this is a democratic playlist, if so remove it completely if ($demo_id && isset($democratic)) { $democratic->delete_from_oid($oid, $type); } header('HTTP/1.1 404 File Disabled'); exit; } // If we are running in Legalize mode, don't play medias already playing if (AmpConfig::get('lock_songs')) { if (!Stream::check_lock_media($media->id, $type)) { exit; } } $media = $catalog->prepare_media($media);
/** * set_include_override * This sets the including div override, used only one place. Kind of a * hack. */ public static function set_include_override($value) { self::$include_override = make_bool($value); }
/** * set_static_content * This sets true/false if the content of this browse * should be static, if they are then content filtering/altering * methods will be skipped * @param boolean $value */ public function set_static_content($value) { $value = make_bool($value); $this->_state['static'] = $value; }
public function get_chunk() { $chunk = null; if (!$this->is_init) { $this->init_channel_songs(); } if ($this->is_init) { // Move to next song while ($this->media == null && ($this->random || $this->song_pos < count($this->songs))) { if ($this->random) { $randsongs = $this->playlist->get_random_items(1); $this->media = new Song($randsongs[0]['object_id']); } else { $this->media = new Song($this->songs[$this->song_pos]); } $this->media->format(); if ($this->media->catalog) { $catalog = Catalog::create_from_id($this->media->catalog); if (make_bool($this->media->enabled)) { if (AmpConfig::get('lock_songs')) { if (!Stream::check_lock_media($this->media->id, 'song')) { debug_event('channel', 'Media ' . $this->media->id . ' locked, skipped.', '3'); $this->media = null; } } } if ($this->media != null) { $this->media = $catalog->prepare_media($this->media); if (!$this->media->file || !Core::is_readable(Core::conv_lc_file($this->media->file))) { debug_event('channel', 'Cannot read media ' . $this->media->id . ' file, skipped.', '3'); $this->media = null; } else { $valid_types = $this->media->get_stream_types(); if (!in_array('transcode', $valid_types)) { debug_event('channel', 'Missing settings to transcode ' . $this->media->file . ', skipped.', '3'); $this->media = null; } else { debug_event('channel', 'Now listening to ' . $this->media->file . '.', '5'); } } } } else { debug_event('channel', 'Media ' . $this->media->id . ' doesn\'t have catalog, skipped.', '3'); $this->media = null; } $this->song_pos++; // Restart from beginning for next song if the channel is 'loop' enabled // and load fresh data from database if ($this->media != null && $this->song_pos == count($this->songs) && $this->loop) { $this->init_channel_songs(); } } if ($this->media != null) { // Stream not yet initialized for this media, start it if (!$this->transcoder) { $this->transcoder = Stream::start_transcode($this->media, $this->stream_type, $this->bitrate); $this->media_bytes_streamed = 0; } if (is_resource($this->transcoder['handle'])) { $chunk = fread($this->transcoder['handle'], 4096); $this->media_bytes_streamed += strlen($chunk); // End of file, prepare to move on for next call if (feof($this->transcoder['handle'])) { $this->media->set_played(); if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { fread($this->transcoder['stderr'], 4096); fclose($this->transcoder['stderr']); } fclose($this->transcoder['handle']); proc_close($this->transcoder['process']); $this->media = null; $this->transcoder = null; } } else { $this->media = null; $this->transcoder = null; } if (!strlen($chunk)) { $chunk = $this->get_chunk(); } } } return $chunk; }
/** * set_enabled * Changes the value of enabled * @param bool|null $value */ public static function set_enabled($value = null) { if (is_null($value)) { self::$enabled = self::$enabled ? false : true; } else { self::$enabled = make_bool($value); } $_SESSION['art_enabled'] = self::$enabled; //setcookie('art_enabled', self::$enabled, time() + 31536000, "/"); }
/** * create * * This takes a keyed array of data and trys to insert it as a * new ACL entry */ public static function create($data) { if (!self::_verify_range($data['start'], $data['end'])) { return false; } // Check existing ACLs to make sure we're not duplicating values here if (self::exists($data)) { debug_event('ACL Create', 'Error: An ACL equal to the created one already exists. Not adding another one: ' . $data['start'] . ' - ' . $data['end'], 1); Error::add('general', T_('Duplicate ACL defined')); return false; } $start = @inet_pton($data['start']); $end = @inet_pton($data['end']); $name = $data['name']; $user = $data['user'] ?: '-1'; $level = intval($data['level']); $type = self::validate_type($data['type']); $enabled = make_bool($data['enabled']) ? 1 : 0; $sql = 'INSERT INTO `access_list` (`name`, `level`, `start`, `end`, ' . '`user`,`type`,`enabled`) VALUES (?, ?, ?, ?, ?, ?, ?)'; Dba::write($sql, array($name, $level, $start, $end, $user, $type, $enabled)); return true; }
/** * invert_bool * This returns the opposite of what you've got */ function invert_bool($value) { return make_bool($value) ? false : true; }
/** * _get_extra_info * This pulls the extra information from our tables, this is a 3 table join, which is why we don't normally * do it */ private function _get_extra_info() { if (parent::is_cached('album_extra', $this->id)) { return parent::get_from_cache('album_extra', $this->id); } $sql = "SELECT " . "COUNT(DISTINCT(`song`.`artist`)) AS `artist_count`, " . "COUNT(`song`.`id`) AS `song_count`, " . "SUM(`song`.`time`) as `total_duration`," . "`song`.`catalog` as `catalog_id`," . "`artist`.`name` AS `artist_name`, " . "`artist`.`prefix` AS `artist_prefix`, " . "`artist`.`id` AS `artist_id` " . "FROM `song` INNER JOIN `artist` " . "ON `artist`.`id`=`song`.`artist` "; if (AmpConfig::get('catalog_disable')) { $sql .= "LEFT JOIN `catalog` ON `catalog`.`id` = `song`.`catalog` "; } $suite_array = array(); if ($this->allow_group_disks) { $suite_array = $this->album_suite; } if (!count($suite_array)) { $suite_array[] = $this->id; } $idlist = '(' . implode(',', $suite_array) . ')'; $sql .= "WHERE `song`.`album` IN {$idlist} "; if (AmpConfig::get('catalog_disable')) { $sql .= "AND `catalog`.`enabled` = '1' "; } if (!count($this->album_suite)) { $sql .= "GROUP BY `song`.`album`"; } else { $sql .= "GROUP BY `song`.`artist`"; } $db_results = Dba::read($sql); $results = Dba::fetch_assoc($db_results); $art = new Art($this->id, 'album'); $art->get_db(); $results['has_art'] = make_bool($art->raw); $results['has_thumb'] = make_bool($art->thumb); if (AmpConfig::get('show_played_times')) { $results['object_cnt'] = Stats::get_object_count('album', $this->id); } parent::add_to_cache('album_extra', $this->id, $results); return $results; }
/** * media_to_urlarray * Formats the URL and media information and adds it to the object */ public static function media_to_urlarray($media, $additional_params = '') { $urls = array(); foreach ($media as $medium) { $url = array(); if ($medium['custom_play_action']) { $additional_params .= "&custom_play_action=" . $medium['custom_play_action']; } $type = $medium['object_type']; //$url['object_id'] = $medium['object_id']; $url['type'] = $type; $object = new $type($medium['object_id']); $object->format(); // Don't add disabled media objects to the stream playlist // Playing a disabled media return a 404 error that could make failed the player (mpd ...) if (make_bool($object->enabled)) { //FIXME: play_url shouldn't be static $url['url'] = $type::play_url($object->id, $additional_params); $api_session = AmpConfig::get('require_session') ? Stream::$session : false; // Set a default which can be overridden $url['author'] = 'Ampache'; $url['time'] = $object->time; switch ($type) { case 'song': $url['title'] = $object->title; $url['author'] = $object->f_artist_full; $url['info_url'] = $object->f_link; $url['image_url'] = Art::url($object->album, 'album', $api_session); $url['album'] = $object->f_album_full; break; case 'video': $url['title'] = 'Video - ' . $object->title; $url['author'] = $object->f_artist_full; break; case 'radio': $url['title'] = 'Radio - ' . $object->name; if (!empty($object->site_url)) { $url['title'] .= ' (' . $object->site_url . ')'; } $url['codec'] = $object->codec; break; case 'song_preview': $url['title'] = $object->title; $url['author'] = $object->f_artist_full; break; case 'channel': $url['title'] = $object->name; break; case 'random': $url['title'] = 'Random URL'; break; default: $url['title'] = 'URL-Add'; $url['time'] = -1; break; } $urls[] = new Stream_URL($url); } } return $urls; }
$media = new Video($oid); if (isset($_REQUEST['subtitle'])) { $subtitle = $media->get_subtitle_file($_REQUEST['subtitle']); } $media->format(); } if (!User::stream_control(array(array('object_type' => $type, 'object_id' => $media->id)))) { debug_event('UI::access_denied', 'Stream control failed for user ' . $GLOBALS['user']->username . ' on ' . $media->get_stream_name(), 3); UI::access_denied(); exit; } if ($media->catalog) { // Build up the catalog for our current object $catalog = Catalog::create_from_id($media->catalog); /* If the media is disabled */ if (isset($media->enabled) && !make_bool($media->enabled)) { debug_event('Play', "Error: {$media->file} is currently disabled, song skipped", '5'); // Check to see if this is a democratic playlist, if so remove it completely if ($demo_id && isset($democratic)) { $democratic->delete_from_oid($oid, $type); } header('HTTP/1.1 404 File Disabled'); exit; } // If we are running in Legalize mode, don't play medias already playing if (AmpConfig::get('lock_songs')) { if (!Stream::check_lock_media($media->id, $type)) { exit; } } $media = $catalog->prepare_media($media);
/** * update * This takes a key'd array of data as input and updates a shoutbox entry */ public static function update($data) { $id = Dba::escape($data['shout_id']); $text = Dba::escape(strip_tags($data['comment'])); $sticky = make_bool($data['sticky']); $sql = "UPDATE `user_shout` SET `text`='{$text}', `sticky`='{$sticky}' WHERE `id`='{$id}'"; Dba::write($sql); return true; }
/** * media_object_to_url */ public static function media_object_to_url($object, $additional_params = '', $urltype = 'web') { $surl = null; $url = array(); $type = strtolower(get_class($object)); $url['type'] = $type; // Don't add disabled media objects to the stream playlist // Playing a disabled media return a 404 error that could make failed the player (mpd ...) if (!isset($object->enabled) || make_bool($object->enabled)) { if ($urltype == 'file') { $url['url'] = $object->file; // Relative path if (!empty($additional_params) && strpos($url['url'], $additional_params) === 0) { $url['url'] = substr($url['url'], strlen($additional_params)); if (strlen($url['url']) < 1) { return null; } if ($url['url'][0] == DIRECTORY_SEPARATOR) { $url['url'] = substr($url['url'], 1); } } } else { //FIXME: play_url shouldn't be static $url['url'] = $type::play_url($object->id, $additional_params); } $api_session = AmpConfig::get('require_session') ? Stream::get_session() : false; // Set a default which can be overridden $url['author'] = 'Ampache'; $url['time'] = $object->time; switch ($type) { case 'song': $url['title'] = $object->title; $url['author'] = $object->f_artist_full; $url['info_url'] = $object->f_link; $url['image_url'] = Art::url($object->album, 'album', $api_session, AmpConfig::get('ajax_load') ? 3 : 4); $url['album'] = $object->f_album_full; $url['track_num'] = $object->f_track; break; case 'video': $url['title'] = 'Video - ' . $object->title; $url['author'] = $object->f_artist_full; $url['resolution'] = $object->f_resolution; break; case 'live_stream': $url['title'] = 'Radio - ' . $object->name; if (!empty($object->site_url)) { $url['title'] .= ' (' . $object->site_url . ')'; } $url['codec'] = $object->codec; break; case 'song_preview': $url['title'] = $object->title; $url['author'] = $object->f_artist_full; break; case 'channel': $url['title'] = $object->name; break; case 'random': $url['title'] = 'Random URL'; break; default: $url['title'] = 'URL-Add'; $url['time'] = -1; break; } $surl = new Stream_URL($url); } return $surl; }
/** * a wrapper for make_bool that safely takes a value out of an array * * @author Craig Ulliott */ function array_val_bool(array $array, $key, $default = false) { return make_bool(array_val($array, $key, $default)); }
/** * check_function * * This checks if specific functionality is enabled. * @param string $type * @return boolean */ public static function check_function($type) { switch ($type) { case 'download': return make_bool(AmpConfig::get('download')); case 'batch_download': if (!function_exists('gzcompress')) { debug_event('access', 'ZLIB extension not loaded, batch download disabled', 3); return false; } if (AmpConfig::get('allow_zip_download') and $GLOBALS['user']->has_access('5')) { return make_bool(AmpConfig::get('download')); } break; } return false; }
/** * localplay * This is for controling localplay */ public static function localplay($input) { // Load their localplay instance $localplay = new Localplay(AmpConfig::get('localplay_controller')); $localplay->connect(); switch ($input['command']) { case 'next': case 'prev': case 'play': case 'stop': $result_status = $localplay->{$input}['command'](); $xml_array = array('localplay' => array('command' => array($input['command'] => make_bool($result_status)))); echo XML_Data::keyed_array($xml_array); break; default: // They are doing it wrong echo XML_Data::error('405', T_('Invalid Request')); break; } // end switch on command }
$localplay->connect(); $localplay->repeat(make_bool($_REQUEST['value'])); ob_start(); $objects = $localplay->get(); require_once AmpConfig::get('prefix') . UI::find_template('show_localplay_status.inc.php'); $results['localplay_status'] = ob_get_contents(); ob_end_clean(); break; case 'random': // Make sure that they have access to do this if (!Access::check('localplay', '50')) { debug_event('DENIED', 'Attempted to set random without access', '1'); exit; } // Scrub her in $localplay = new Localplay(AmpConfig::get('localplay_controller')); $localplay->connect(); $localplay->random(make_bool($_REQUEST['value'])); ob_start(); $objects = $localplay->get(); require_once AmpConfig::get('prefix') . UI::find_template('show_localplay_status.inc.php'); $results['localplay_status'] = ob_get_contents(); ob_end_clean(); break; default: $results['rfc3514'] = '0x1'; break; } // switch on action; // We always do this echo xoutput_from_array($results);
/** * set_static_content * This sets true/false if the content of this browse * should be static, if they are then content filtering/altering * methods will be skipped */ public function set_static_content($value) { $value = make_bool($value); // We want to start at 0 if it's static if ($value) { $this->set_start('0'); } $this->_state['static'] = $value; }
public function get_chunk() { $chunk = null; if (!$this->is_init) { $this->init_channel_songs(); } if ($this->is_init) { // Move to next song while ($this->media == null && ($this->random || $this->song_pos < count($this->songs))) { if ($this->random) { $randsongs = $this->playlist->get_random_items(1); $this->media = new Song($randsongs[0]['object_id']); } else { $this->media = new Song($this->songs[$this->song_pos]); } $this->media->format(); if ($this->media->catalog) { $catalog = Catalog::create_from_id($this->media->catalog); if (make_bool($this->media->enabled)) { if (AmpConfig::get('lock_songs')) { if (!Stream::check_lock_media($this->media->id, 'song')) { debug_event('channel', 'Media ' . $this->media->id . ' locked, skipped.', '3'); $this->media = null; } } } if ($this->media != null) { $this->media = $catalog->prepare_media($this->media); if (!$this->media->file || !Core::is_readable(Core::conv_lc_file($this->media->file))) { debug_event('channel', 'Cannot read media ' . $this->media->id . ' file, skipped.', '3'); $this->media = null; } else { $valid_types = $this->media->get_stream_types(); if (!in_array('transcode', $valid_types)) { debug_event('channel', 'Missing settings to transcode ' . $this->media->file . ', skipped.', '3'); $this->media = null; } else { debug_event('channel', 'Now listening to ' . $this->media->file . '.', '5'); } } } } else { debug_event('channel', 'Media ' . $this->media->id . ' doesn\'t have catalog, skipped.', '3'); $this->media = null; } $this->song_pos++; // Restart from beginning for next song if the channel is 'loop' enabled // and load fresh data from database if ($this->media != null && $this->song_pos == count($this->songs) && $this->loop) { $this->init_channel_songs(); } } if ($this->media != null) { // Stream not yet initialized for this media, start it if (!$this->transcoder) { $options = array('bitrate' => $this->bitrate); $this->transcoder = Stream::start_transcode($this->media, $this->stream_type, null, $options); $this->media_bytes_streamed = 0; } if (is_resource($this->transcoder['handle'])) { if (ftell($this->transcoder['handle']) == 0) { $this->header_chunk = ''; } $chunk = fread($this->transcoder['handle'], $this->chunk_size); $this->media_bytes_streamed += strlen($chunk); if (ftell($this->transcoder['handle']) < 10000 && strtolower($this->stream_type) == "ogg" || $this->header_chunk_remainder) { //debug_event('channel', 'File handle pointer: ' . ftell($this->transcoder['handle']) ,'5'); $clchunk = $chunk; if ($this->header_chunk_remainder) { $this->header_chunk .= substr($clchunk, 0, $this->header_chunk_remainder); if (strlen($clchunk) >= $this->header_chunk_remainder) { $clchunk = substr($clchunk, $this->header_chunk_remainder); $this->header_chunk_remainder = 0; } else { $this->header_chunk_remainder = $this->header_chunk_remainder - strlen($clchunk); $clchunk = ''; } } // see bin/channel_run.inc for explanation what's happening here while ($this->strtohex(substr($clchunk, 0, 4)) == "4F676753") { $hex = $this->strtohex(substr($clchunk, 0, 27)); $ogg_nr_of_segments = hexdec(substr($hex, 26 * 2, 2)); if (substr($clchunk, 27 + $ogg_nr_of_segments + 1, 6) == "vorbis" || substr($clchunk, 27 + $ogg_nr_of_segments, 4) == "Opus") { $hex .= $this->strtohex(substr($clchunk, 27, $ogg_nr_of_segments)); $ogg_sum_segm_laces = 0; for ($segm = 0; $segm < $ogg_nr_of_segments; $segm++) { $ogg_sum_segm_laces += hexdec(substr($hex, 27 * 2 + $segm * 2, 2)); } $this->header_chunk .= substr($clchunk, 0, 27 + $ogg_nr_of_segments + $ogg_sum_segm_laces); if (strlen($clchunk) < 27 + $ogg_nr_of_segments + $ogg_sum_segm_laces) { $this->header_chunk_remainder = (int) (27 + $ogg_nr_of_segments + $ogg_sum_segm_laces - strlen($clchunk)); } $clchunk = substr($clchunk, 27 + $ogg_nr_of_segments + $ogg_sum_segm_laces); } else { //no more interesting headers $clchunk = ''; } } } //debug_event('channel', 'File handle pointer: ' . ftell($this->transcoder['handle']) ,'5'); //debug_event('channel', 'CHUNK : ' . $chunk, '5'); //debug_event('channel', 'Chunk size: ' . strlen($chunk) ,'5'); // End of file, prepare to move on for next call if (feof($this->transcoder['handle'])) { $this->media->set_played(-1, 'Ampache', array()); if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') { fread($this->transcoder['stderr'], 4096); fclose($this->transcoder['stderr']); } fclose($this->transcoder['handle']); Stream::kill_process($this->transcoder); $this->media = null; $this->transcoder = null; } } else { $this->media = null; $this->transcoder = null; } if (!strlen($chunk)) { $chunk = $this->get_chunk(); } } } return $chunk; }
/** * update * This takes a key'd array of data as input and updates a shoutbox entry */ public function update(array $data) { $sql = "UPDATE `user_shout` SET `text` = ?, `sticky` = ? WHERE `id` = ?"; Dba::write($sql, array($data['comment'], make_bool($data['sticky']), $this->id)); return $this->id; }
/** * update_preference * This function updates a single preference and is called by the update_preferences function */ function update_preference($user_id, $name, $pref_id, $value) { $apply_check = "check_" . $name; $level_check = "level_" . $name; /* First see if they are an administrator and we are applying this to everything */ if ($GLOBALS['user']->has_access(100) and make_bool($_REQUEST[$apply_check])) { Preference::update_all($pref_id, $value); return true; } /* Check and see if they are an admin and the level def is set */ if ($GLOBALS['user']->has_access(100) and make_bool($_REQUEST[$level_check])) { Preference::update_level($pref_id, $_REQUEST[$level_check]); } /* Else make sure that the current users has the right to do this */ if (Preference::has_access($name)) { $sql = "UPDATE `user_preference` SET `value` = ? WHERE `preference` = ? AND `user` = ?"; Dba::write($sql, array($value, $pref_id, $user_id)); return true; } return false; }
/** * _mangle_data * * Private convenience function. Mangles the input according to a set * of predefined rules so that we don't have to include this logic in * foo_to_sql. */ private function _mangle_data($data, $type, $operator) { if ($operator['preg_match']) { $data = preg_replace($operator['preg_match'], $operator['preg_replace'], $data); } if ($type == 'numeric') { return intval($data); } if ($type == 'boolean') { return make_bool($data); } return $data; }
/** * Get stream types for media type. * @param string $type * @return string */ public static function get_stream_types_for_type($type, $player = null) { $types = array(); $transcode = AmpConfig::get('transcode_' . $type); if ($player) { $player_transcode = AmpConfig::get('transcode_player_' . $player . '_' . $type); if ($player_transcode) { $transcode = $player_transcode; } } if ($transcode != 'required') { $types[] = 'native'; } if (make_bool($transcode)) { $types[] = 'transcode'; } return $types; }