diff --git a/api.php b/api.php index c601d6c..3253188 100644 --- a/api.php +++ b/api.php @@ -1,332 +1,332 @@ * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource * @todo Consider to output documentation on / and /ship queries * @todo /app/getdata */ //API preferences define('URL', 'http://' . $_SERVER['HTTP_HOST'] . '/index.php'); //Pluton library require_once('includes/core.php'); require_once('includes/config.php'); //API libs require_once('includes/api/api_helpers.php'); require_once('includes/api/cerbere.php'); //Use our URL controller method if you want to mod_rewrite the API $Config['SiteURL'] = get_server_url() . $_SERVER["PHP_SELF"]; $url = get_current_url_fragments(); switch ($module = $url[0]) { /* ------------------------------------------------------------- Site API /time /location /coordinates - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case '': //Nothing to do //TODO: offer documentation instead die(); case 'time': //Hypership time api_output(get_hypership_time(), "time"); break; case 'location': //Checks credentials cerbere(); //Gets location info require_once("includes/geo/location.php"); $location = new GeoLocation($url[1], $url[2]); api_output($location, "location"); break; case 'coordinates': //Checks credentials cerbere(); //Get coordinates api_output(GeoGalaxy::getCoordinates(), 'galaxy', 'object'); break; /* ------------------------------------------------------------- Ship API /authenticate /appauthenticate /appauthenticated /move /land /flyout - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case 'ship': //Ship API //Gets ship from Ship API key (distinct of regular API keys) require_once('includes/objects/ship.php'); $ship = Ship::from_api_key($_REQUEST['key']) or cerbere_die("Invalid ship API key"); switch ($command = $url[1]) { case '': //Nothing to do //TODO: offer documentation instead die(); case 'authenticate': //TODO: web authenticate break; case 'appauthenticate': //Allows desktop application to authenticate an user $tmp_session_id = $url[2] or cerbere_die("/appauthenticate/ must be followed by any session identifier"); if ($_REQUEST['name']) { //Perso will be offered auth invite at next login. //Handy for devices like PDA, where it's not easy to auth. $perso = new Perso($_REQUEST['name']); if ($perso->lastError) { cerbere_die($perso->lastError); } if (!$ship->is_perso_authenticated($perso->id)) { $ship->request_perso_authenticate($perso->id); } $ship->request_perso_confirm_session($tmp_session_id, $perso->id); } else { //Delivers an URL. App have to redirects user to this URL //launching a browser or printing the link. $ship_code = $ship->get_code(); registry_set("api.ship.session.$ship_code.$tmp_session_id", -1); $url = get_server_url() . get_url() . "?action=api.ship.appauthenticate&session_id=" . $tmp_session_id; api_output($url, "URL"); } break; case 'appauthenticated': //Checks the user authentication $tmp_session_id = $url[2] or cerbere_die("/appauthenticated/ must be followed by any session identifier you used in /appauthenticate"); $perso_id = $ship->get_perso_from_session($tmp_session_id); if (!$isPersoAuth = $ship->is_perso_authenticated($perso_id)) { //Global auth not ok/revoked. $auth->status = -1; } else { $perso = Perso::get($perso_id); $auth->status = 1; $auth->perso->id = $perso->id; $auth->perso->nickname = $perso->nickname; $auth->perso->name = $perso->name; //$auth->perso->location = $perso->location; //Is the perso on board? Yes if its global location is S... $auth->perso->onBoard = ( $perso->location_global[0] == 'S' && substr($perso->location_global, 1, 5) == $ship->id ); if ($auth->perso->onBoard) { //If so, give local location $auth->perso->location_local = $perso->location_local; } } api_output($auth, "auth"); break; case 'move': //Moves the ship to a new location, given absolute coordinates //TODO: handle relative moves if (count($url) < 2) { cerbere_die("/move/ must be followed by a location expression"); } //Gets location class //It's allow: (1) to normalize locations between formats // (2) to ensure the syntax //==> if the ship want to communicate free forms coordinates, must be added on GeoLocation a free format try { $location = new GeoLocation($url[2]); } catch (Exception $ex) { $reply->success = 0; $reply->error = $ex->getMessage(); api_output($reply, "move"); break; } $ship->location_global = $location->global; $ship->save_to_database(); $reply->success = 1; $reply->location = $ship->location; api_output($reply, "move"); break; case 'land': case 'flyin': //Flies in try { $location = new GeoLocation($location); } catch (Exception $ex) { $reply->success = 0; $reply->error = $ex->getMessage(); api_output($reply, "land"); break; } break; case 'flyout': //Flies out break; } break; /* ------------------------------------------------------------- Application API /checkuserkey - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case 'app': //Application API require_once("includes/objects/application.php"); $app = Application::from_api_key($_REQUEST['key']) or cerbere_die("Invalid application API key"); switch ($command = $url[1]) { case '': //Nothing to do //TODO: offer documentation instead die(); case 'checkuserkey': if (count($url) < 2) { cerbere_die("/checkuserkey/ must be followed by an user key"); } $reply = (boolean)$app->get_perso_id($url[2]); api_output($reply, "check"); break; case 'pushuserdata': if (count($url) < 3) { cerbere_die("/pushuserdata/ must be followed by an user key"); } $perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key"); //then, falls to 'pushdata' case 'pushdata': - $data_id = $_REQUEST['data'] ? $_REQUEST['data'] : new_guid(); + $data_id = $_REQUEST['data'] ?: new_guid(); //Gets data switch ($mode = $_REQUEST['mode']) { case '': cerbere_die("Add in your data posted or in the URL mode=file to read data from the file posted (one file per api call) or mode=request to read data from \$_REQUEST['data']."); case 'request': $data = $_REQUEST['data']; $format = "raw"; break; case 'file': $file = $_FILES['datafile']['tmp_name'] or cerbere_die("File is missing"); if (!is_uploaded_file($file)) { cerbere_die("Invalid form request"); } $data = ""; if (preg_match('/\.tar$/', $file)) { $format = "tar"; $data = file_get_contents($file); } elseif (preg_match('/\.tar\.bz2$/', $file)) { $format = "tar"; } elseif (preg_match('/\.bz2$/', $file)) { $format = "raw"; } else { $format = "raw"; $data = file_get_contents($file); } if ($data === "") { //.bz2 $bz = bzopen($file, "r") or cerbere_die("Couldn't open $file"); while (!feof($bz)) { $data .= bzread($bz, BUFFER_SIZE); } bzclose($bz); } unlink($file); break; default: cerbere_die("Invalid mode. Expected: file, request"); } //Saves data global $db; $data_id = $db->sql_escape($data_id); $data = $db->sql_escape($data); - $perso_id = $perso_id ? $perso_id : 'NULL'; + $perso_id = $perso_id ?: 'NULL'; $sql = "REPLACE INTO applications_data (application_id, data_id, data_content, data_format, perso_id) VALUES ('$app->id', '$data_id', '$data', '$format', $perso_id)"; if (!$db->sql_query($sql)) { message_die(SQL_ERROR, "Can't save data", '', __LINE__, __FILE__, $sql); } //cerbere_die("Can't save data"); //Returns api_output($data_id); break; case 'getuserdata': // /api.php/getuserdata/data_id/perso_key // /api.php/getdata/data_id if (count($url) < 3) { cerbere_die("/getuserdata/ must be followed by an user key"); } $perso_id = $app->get_perso_id($url[2]) or cerbere_die("Invalid application user key"); //then, falls to 'getdata' case 'getdata': if (count($url) < 2) { cerbere_die('/' . $url[0] . '/ must be followed by the data ID'); } if (!$perso_id) { $perso_id = 'NULL'; } $data_id = $db->sql_escape($url[1]); $sql = "SELECT data_content FROM applications_data WHERE application_id = '$app->id' AND data_id = '$data_id' AND perso_id = $perso_id"; if (!$result = $db->sql_query($sql)) { message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql); } while ($row = $db->sql_fetchrow($result)) { } break; default: echo "Unknown module:"; dprint_r($url); break; } break; default: echo "Unknown module:"; dprint_r($url); break; } diff --git a/controllers/profile.php b/controllers/profile.php index ae7b7d3..e11fad7 100644 --- a/controllers/profile.php +++ b/controllers/profile.php @@ -1,353 +1,353 @@ views the nickname's profile, * /who/random views a random profile, * /who/edit/profile edits its profile * /who/edit/account edits its account (disabled on Zed, cf. settings), * /who/edit/photo(s) manages its profile's photos, * /who/edit/photo/edit/ edits a photo properties, * /who/edit/photo/delete/ deletes a photo, * /who/edit/photo/avatar/ promotes a photo to avatar. * * The following views are used: * profile.tpl, * profile_edit.tpl, * user_account.tpl, * profile_photo.tpl, * profile_photo_edit.tpl. * * The following models are used: * Profile, * ProfilePhoto, * ProfileComment. * * The view profile_tags.tpl is indirectly used by the Profile model. * * This code is maintained in // with Azhàr. * * @package Zed * @subpackage Controllers * @author Sébastien Santoro aka Dereckson * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource */ //Loads language file lang_load('profile.conf'); //Gets perso nickname from URL $who = $url[1]; switch ($who) { case 'edit': $mode = 'edit'; $who = $CurrentPerso->nickname; break; case 'random': $mode = 'view'; $who = $db->sql_query_express("SELECT perso_id FROM " . TABLE_PROFILES . " ORDER BY rand() LIMIT 1"); break; default: $mode = 'view'; } if (!$who) { message_die(GENERAL_ERROR, "Who?", "URL error"); } //Libs require_once('includes/objects/profile.php'); require_once('includes/objects/profilecomment.php'); require_once('includes/objects/profilephoto.php'); //Gets perso information require_once('includes/objects/perso.php'); $perso = Perso::get($who); if ($perso->lastError) { message_die(GENERAL_ERROR, $perso->lastError, "Error"); } $smarty->assign('perso', $perso); //Gets profile $profile = new Profile($perso->id); //Handles form if ($_POST['EditProfile']) { $profile->load_from_form(); $profile->updated = time(); $profile->save_to_database(); $mode = 'view'; } elseif ($_POST['UserAccount']) { $smarty->assign('WAP', "This form have been deprecated. You can write instead settings in the SmartLine"); } elseif ($_POST['message_type'] == 'private_message') { //Sends a message require_once('includes/objects/message.php'); $msg = new Message(); $msg->from = $CurrentPerso->id; $msg->to = $perso->id; $msg->text = $_POST['message']; $msg->send(); if ($msg->from == $msg->to) { $smarty->assign('NOTIFY', lang_get('MessageSentSelf')); } else { $smarty->assign('NOTIFY', lang_get('MessageSent')); } } elseif ($_POST['message_type'] == 'profile_comment') { //New profile comment $comment = new ProfileComment(); $comment->author = $CurrentPerso->id; $comment->perso_id = $perso->id; $comment->text = $_POST['message']; $comment->publish(); $smarty->assign('NOTIFY', lang_get('CommentPublished')); } elseif ($_FILES['photo']) { #We've a file ! $hash = md5(microtime() . serialize($_FILES)); $extension = get_extension($_FILES['photo']['name']); $filename = $CurrentPerso->id . '_' . $hash . '.' . $extension; #We ignore $_FILES[photo][error] 4, this means no file has been uploaded #(so user doesn't want upload a new file) #See http:/www.php.net/features.file-upload and http://www.php.net/manual/en/features.file-upload.errors.php about common errors #Not valid before PHP 4.2.0 switch ($_FILES['photo']['error']) { case 0: #There is no error, the file uploaded with success. if (!move_uploaded_file($_FILES['photo']['tmp_name'], PHOTOS_DIR . '/' . $filename)) { $errors[] = "Upload successful, but error saving it."; } else { //Attaches the picture to the profile $photo = new ProfilePhoto(); $photo->name = $filename; $photo->perso_id = $CurrentPerso->id; $photo->description = $_POST['description']; if ($photo->avatar) { $photo->promote_to_avatar(); } $photo->save_to_database(); //Generates thumbnail if (!$photo->generate_thumbnail()) { $smarty->assign('WAP', "Error generating thumbnail."); } $smarty->assign('NOTIFY', lang_get('PhotoUploaded')); $mode = 'view'; } break; case 1: $errors[] = "The file is too large."; break; #TODO : more explicit error messages default: $errors[] = "Unknown error (#" . $_FILES['photo']['error'] . ")"; break; } if (count($errors)) { $smarty->assign('WAP', join('
', $errors)); } } elseif ($_POST['id']) { //Edits photo properties $photo = new ProfilePhoto($_POST['id']); if ($photo->lastError) { $smarty->assign('WAP', $photo->lastError); $mode = 'view'; } elseif ($photo->perso_id != $CurrentPerso->id) { $smarty->assign('WAP', lang_get('NotYourPic')); $mode = 'view'; } else { //OK $wereAvatar = $photo->avatar; $photo->load_from_form(); if (!$wereAvatar && $photo->avatar) { //Promote to avatar $photo->promote_to_avatar(); } $photo->save_to_database(); } } //Prepares output if ($profile->text) { //Profile $smarty->assign('PROFILE_TEXT', $profile->text); $smarty->assign('PROFILE_FIXEDWIDTH', $profile->fixedwidth); } if ($mode == 'view') { require_once('includes/objects/profilephoto.php'); //Self profile? $self = $CurrentPerso->id == $profile->perso_id; //Gets profiles comments, photos, tags $comments = ProfileComment::get_comments($profile->perso_id); $photos = ProfilePhoto::get_photos($profile->perso_id); $tags = $profile->get_cached_tags(); //Records timestamp, to be able to track new comments if ($self) { $CurrentPerso->set_flag('profile.lastvisit', time()); } //Template $smarty->assign('PROFILE_COMMENTS', $comments); $smarty->assign('PROFILE_SELF', $self); if ($tags) { $smarty->assign('PROFILE_TAGS', $tags); } $smarty->assign('USERNAME', $perso->username); - $smarty->assign('NAME', $perso->name ? $perso->name : $perso->nickname); + $smarty->assign('NAME', $perso->name ?: $perso->nickname); $template = 'profile.tpl'; } elseif ($mode == 'edit') { switch ($url[2]) { case 'profile': $smarty->assign('USERNAME', $perso->name); $smarty->assign('DIJIT', true); $css[] = THEME . '/forms.css'; $template = 'profile_edit.tpl'; break; case 'account': $smarty->assign('user', $CurrentUser); $smarty->assign('DIJIT', true); $css[] = THEME . '/forms.css'; $template = 'user_account.tpl'; break; case '': $smarty->assign('NOTIFY', "What do you want to edit ? Append /profile, /account or /photos to the URL"); break; case 'photo': case 'photos': $smarty->assign('USERNAME', $perso->name); switch ($action = $url[3]) { case '': //Nothing to do break; case 'delete': //Deletes a picture if (!$id = $url[4]) { $smarty->assign('WAP', "URL error. Parameter missing: picture id."); } else { $photo = new ProfilePhoto($id); if ($photo->lastError) { //Probably an non existent id (e.g. double F5, photo already deleted) $smarty->assign('WAP', $photo->lastError); } elseif ($photo->perso_id != $CurrentPerso->id) { $smarty->assign('WAP', lang_get('NotYourPic')); } else { //OK we can delete it $photo->delete(); $smarty->assign('NOTIFY', lang_get('PictureDeleted')); } } break; case 'edit': if (!$id = $url[4]) { $smarty->assign('WAP', "URL error. Parameter missing: picture id."); } else { $photo = new ProfilePhoto($id); if ($photo->lastError) { //Probably an non existent id (e.g. double F5, photo already deleted) $smarty->assign('WAP', $photo->lastError); } elseif ($photo->perso_id != $CurrentPerso->id) { $smarty->assign('WAP', lang_get('NotYourPic')); } else { //Photo information edit form $smarty->assign('photo', $photo); $template = 'profile_photo_edit.tpl'; } } break; case 'avatar': //Promotes a picture to avatar if (!$id = $url[4]) { $smarty->assign('WAP', "URL error. Parameter missing: picture id."); } else { $photo = new ProfilePhoto($id); if ($photo->lastError) { $smarty->assign('WAP', $photo->lastError); } elseif ($photo->perso_id != $CurrentPerso->id) { $smarty->assign('WAP', lang_get('NotYourPic')); } else { //OK, promote it to avatar $photo->promote_to_avatar(); $photo->save_to_database(); $smarty->assign('NOTIFY', lang_get('PromotedToAvatar')); } } break; default: $smarty->assign('WAP', "Unknown URL. To delete a picture it's /delete/. To edit it /edit/"); break; } if (!$template) { $photos = ProfilePhoto::get_photos($profile->perso_id); if (!$smarty->tpl_vars['NOTIFY']) { $smarty->assign('NOTIFY', "Your feedback is valued. Report any bug or suggestion on the graffiti wall."); } $template = 'profile_photo.tpl'; } break; default: $smarty->assign('WAP', "URL error. You can use /edit with profile, account or photos."); break; } } // // HTML output // //Photos if (count($photos) || $photo) { $smarty->assign('URL_PICS', PHOTOS_URL); $css[] = 'lightbox.css'; $smarty->assign('PAGE_JS', ['prototype.js', 'effects.js', 'lightbox.js']); $smarty->assign('PICS', $photos); } //Serves header $css[] = THEME . "/profile.css"; $smarty->assign('PAGE_CSS', $css); $smarty->assign('PAGE_TITLE', $perso->name); include('header.php'); //Serves content if ($template) { $smarty->display($template); } //Serves footer include('footer.php'); diff --git a/controllers/usersearch.php b/controllers/usersearch.php index eac0ad1..4a0f4a3 100644 --- a/controllers/usersearch.php +++ b/controllers/usersearch.php @@ -1,118 +1,118 @@ * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource * * @todo implement it */ //Libs require_once('includes/objects/ProfilePhoto.php'); // // Does the search // //Search type switch ($resource = $url[1]) { case '': break; case 'online': $sql = "SELECT u.username, u.user_id, u.user_longname FROM " . TABLE_USERS . " u, " . TABLE_SESSIONS . " s WHERE s.online = 1 AND u.user_id = s.user_id ORDER BY HeureLimite DESC"; if (!$result = $db->sql_query($sql)) { message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql); } $i = 0; while ($row = $db->sql_fetchrow($result)) { $users[$i]->id = $row['user_id']; $users[$i]->username = $row['username']; $users[$i]->longname = $row['user_longname']; $i++; } $title = sprintf(lang_get('UsersOnline'), $i, s($i)); break; case 'directory': $sql = 'SELECT username, user_longname FROM ' . TABLE_USERS . ' WHERE user_active < 2 ORDER by user_longname ASC'; if (!$result = $db->sql_query($sql)) { message_die(SQL_ERROR, "Unable to query the table", '', __LINE__, __FILE__, $sql); } $i = 0; while ($row = $db->sql_fetchrow($result)) { $users[$i]->username = $row['username']; $users[$i]->longname = $row['user_longname']; $i++; } $title = lang_get('Directory'); $mode = 'directory'; break; default: $smarty->assign('WAP', lang_get('Nay')); break; } switch ($mode) { case 'directory': $template = 'directory.tpl'; $smarty->assign('USERS', $users); break; default: //Prepares avatars if (count($users)) { foreach ($users as $user) { - $name = $user->longname ? $user->longname : $user->username; + $name = $user->longname ?: $user->username; $user->avatar = ProfilePhoto::get_avatar($user->id, $name); } } $template = 'usersearch.tpl'; $smarty->assign('TITLE', $title); $smarty->assign('USERS', $users); break; } // // HTML output // //Serves header $smarty->assign('PAGE_CSS', 'usersearch.css'); $smarty->assign('PAGE_TITLE', $title); include('header.php'); //Serves content if ($template) { $smarty->display($template); } //Serves footer include('footer.php'); diff --git a/includes/content/file.php b/includes/content/file.php index 9a23857..9890072 100644 --- a/includes/content/file.php +++ b/includes/content/file.php @@ -1,284 +1,284 @@ * @copyright 2010 Sébastien Santoro aka Dereckson * @license http://www.opensource.org/licenses/bsd-license.php BSD * @version 0.1 * @link http://scherzo.dereckson.be/doc/zed * @link http://zed.dereckson.be/ * @filesource */ /** * Content class * * This class maps the content_files table. * */ class ContentFile { /* ------------------------------------------------------------- Properties - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ public $id; public $path; public $user_id; public $perso_id; public $title; /* ------------------------------------------------------------- Constructor, __toString - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** * Initializes a new ContentFile instance * * @param int $id the primary key */ function __construct ($id = null) { if ($id) { $this->id = $id; $this->load_from_database(); } } /** * Returns a string representation of current Content instance * * @return string the content title or path if title is blank. */ function __toString () { - return $this->title ? $this->title : $this->path; + return $this->title ?: $this->path; } /* ------------------------------------------------------------- Load/save class - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** * Loads the object ContentFile (ie fill the properties) from the $_POST array * * @param boolean $allowSensibleFields if false, allow only title to be defined ; otherwise, allow all fields. */ function load_from_form ($allowSensibleFields = false) { if (array_key_exists('title', $_POST)) { $this->title = $_POST['title']; } if ($allowSensibleFields) { if (array_key_exists('path', $_POST)) { $this->path = $_POST['path']; } if (array_key_exists('user_id', $_POST)) { $this->user_id = $_POST['user_id']; } if (array_key_exists('perso_id', $_POST)) { $this->perso_id = $_POST['perso_id']; } } } /** * Loads the object ContentFile (ie fill the properties) from the database */ function load_from_database () { global $db; $id = $db->sql_escape($this->id); $sql = "SELECT * FROM content_files WHERE content_id = '" . $id . "'"; if ( !($result = $db->sql_query($sql)) ) { message_die(SQL_ERROR, "Unable to query content", '', __LINE__, __FILE__, $sql); } if (!$row = $db->sql_fetchrow($result)) { $this->lastError = "Content unknown: " . $this->id; return false; } $this->load_from_row($row); return true; } /** * Loads the object from row */ function load_from_row ($row) { $this->id = $row['content_id']; $this->path = $row['content_path']; $this->user_id = $row['user_id']; $this->perso_id = $row['perso_id']; $this->title = $row['content_title']; } /** * Saves to database */ function save_to_database () { global $db; $id = $this->id ? "'" . $db->sql_escape($this->id) . "'" : 'NULL'; $path = $db->sql_escape($this->path); $user_id = $db->sql_escape($this->user_id); $perso_id = $db->sql_escape($this->perso_id); $title = $db->sql_escape($this->title); //Updates or inserts $sql = "REPLACE INTO content_files (`content_id`, `content_path`, `user_id`, `perso_id`, `content_title`) VALUES ($id, '$path', '$user_id', '$perso_id', '$title')"; if (!$db->sql_query($sql)) { message_die(SQL_ERROR, "Can't save content", '', __LINE__, __FILE__, $sql); } if (!$this->id) { //Gets new record id value $this->id = $db->sql_nextid(); } } /* ------------------------------------------------------------- File handling helper methods - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ /** * Determines if the extension is valid * * @param string $ext The extension (without dot) * @return boolean true if this extension is valid ; otherwise, false. */ function is_valid_extension ($ext) { $ext = strtolower($ext); return (is_valid_image_extension($ext) || is_valid_audio_extension($ext) || is_valid_video_extension($ext)); } /** * Determines if the extension is valid * * @param string $ext The extension (without dot) * @return boolean true if this extension is valid ; otherwise, false. */ function is_valid_image_extension ($ext) { switch ($ext = strtolower($ext)) { //Pictures case 'jpg': case 'gif': case 'png': case 'bmp': case 'xbm': return true; //Denied extension default: return false; } } /** * Determines if the extension is a valid audio file one * * @param string $ext The extension (without dot) * @return boolean true if this extension is valid ; otherwise, false. */ function is_valid_audio_extension ($ext) { switch ($ext = strtolower($ext)) { //Sounds (HTML5