From 8f3061ab99b934105b21d97bd039afb83f86aab1 Mon Sep 17 00:00:00 2001 From: Cody Cook Date: Sat, 22 Feb 2025 00:20:39 -0800 Subject: [PATCH] Language updates. New upload form. new classes. --- classes/CDN.php | 75 ++ classes/Email.php | 73 ++ classes/HeaderMeta.php | 18 +- classes/Mix.php | 456 ++++++------ classes/SessionManager.php | 39 ++ classes/Upload.php | 160 +++-- classes/User.php | 295 +++++++- composer.json | 13 +- composer.lock | 1358 ++++++++++++++++++++++++++++++------ composer.phar | Bin 2989019 -> 3060478 bytes contact.php | 141 ++-- dj.php | 12 +- includes/footer.php | 31 +- includes/globals.php | 42 +- includes/header-meta.php | 1 - includes/header.php | 15 +- includes/navbar.php | 139 ++-- includes/sessions.php | 8 - locale/af-ZA/messages.php | 7 +- locale/ar-SA/messages.php | 39 +- locale/ca-ES/messages.php | 7 +- locale/cs-CZ/messages.php | 31 +- locale/da-DK/messages.php | 29 +- locale/de-DE/messages.php | 31 +- locale/el-GR/messages.php | 31 +- locale/en-US/messages.php | 13 + locale/es-ES/messages.php | 29 +- locale/fi-FI/messages.php | 29 +- locale/fil-PH/messages.php | 7 +- locale/fr-FR/messages.php | 31 +- locale/he-IL/messages.php | 7 +- locale/hu-HU/messages.php | 7 +- locale/it-IT/messages.php | 31 +- locale/ja-JP/messages.php | 29 +- locale/ko-KR/messages.php | 7 +- locale/nl-NL/messages.php | 31 +- locale/no-NO/messages.php | 29 +- locale/pl-PL/messages.php | 31 +- locale/pt-BR/messages.php | 33 +- locale/pt-PT/messages.php | 33 +- locale/ro-RO/messages.php | 31 +- locale/ru-RU/messages.php | 33 +- locale/sr-SP/messages.php | 7 +- locale/sv-SE/messages.php | 31 +- locale/tr-TR/messages.php | 7 +- locale/uk-UA/messages.php | 31 +- locale/vi-VN/messages.php | 7 +- locale/zh-CN/messages.php | 31 +- locale/zh-TW/messages.php | 7 +- login.php | 58 +- logout.php | 14 + mix.php | 102 +-- phing-latest.phar | Bin 0 -> 25139855 bytes profile.php | 158 ++++- register.php | 106 ++- update_email.php | 97 --- update_name.php | 43 -- update_password.php | 84 --- update_username.php | 53 -- upload.php | 394 +++++++---- upload_details.php | 245 ------- verify_email.php | 53 +- 62 files changed, 3107 insertions(+), 1883 deletions(-) create mode 100644 classes/CDN.php create mode 100644 classes/Email.php create mode 100644 classes/SessionManager.php delete mode 100644 includes/sessions.php create mode 100644 logout.php create mode 100644 phing-latest.phar delete mode 100644 update_email.php delete mode 100644 update_name.php delete mode 100644 update_password.php delete mode 100644 update_username.php delete mode 100644 upload_details.php diff --git a/classes/CDN.php b/classes/CDN.php new file mode 100644 index 0000000..b316d2e --- /dev/null +++ b/classes/CDN.php @@ -0,0 +1,75 @@ +config = $config; + $this->bucket = $config['aws']['s3']['bucket']; + + $credentials = new Credentials( + $config['aws']['s3']['access_key'], + $config['aws']['s3']['secret_key'] + ); + + $this->s3Client = new S3Client([ + 'version' => 'latest', + 'region' => $config['aws']['s3']['region'], + 'endpoint' => $config['aws']['s3']['host'], + 'credentials' => $credentials, + 'use_path_style_endpoint' => true, + 'profile' => null, + 'use_aws_shared_config_files' => false, + ]); + } + + public function uploadFile(string $localPath, string $remotePath, string $mimeType, string $acl = 'private') + { + try { + $result = $this->s3Client->putObject([ + 'Bucket' => $this->bucket, + 'Key' => $remotePath, + 'SourceFile' => $localPath, + 'ACL' => $acl, + 'ContentType' => $mimeType, + ]); + return $result; + } catch (\Exception $e) { + throw new \Exception("Error uploading file to CDN: " . $e->getMessage()); + } + } + + public function renameFile(string $oldRemotePath, string $newRemotePath) + { + // S3 does not support renaming directly. Copy then delete. + try { + $this->s3Client->copyObject([ + 'Bucket' => $this->bucket, + 'CopySource' => "{$this->bucket}/{$oldRemotePath}", + 'Key' => $newRemotePath, + ]); + + $this->s3Client->deleteObject([ + 'Bucket' => $this->bucket, + 'Key' => $oldRemotePath, + ]); + } catch (\Exception $e) { + throw new \Exception("Error renaming file on CDN: " . $e->getMessage()); + } + } + + public function clearCache(string $remotePath) + { + // If using CloudFront or another CDN in front of S3, implement invalidation logic here. + // This might involve calling the CloudFront API to invalidate the specific path. + } +} diff --git a/classes/Email.php b/classes/Email.php new file mode 100644 index 0000000..67c2411 --- /dev/null +++ b/classes/Email.php @@ -0,0 +1,73 @@ +config = $config; + $this->sesClient = new SesClient([ + 'version' => 'latest', + 'region' => $config['aws']['ses']['region'], + 'credentials' => [ + 'key' => $config['aws']['ses']['access_key'], + 'secret' => $config['aws']['ses']['secret_key'] + ] + ]); + } + + /** + * Generic method to send an email. + * + * @param string $recipientEmail + * @param string $subject + * @param string $bodyText + * @throws Exception if email sending fails. + */ + public function sendEmail(string $recipientEmail, string $subject, string $bodyText): void { + $senderEmail = $this->config['aws']['ses']['sender_email']; + try { + $this->sesClient->sendEmail([ + 'Destination' => ['ToAddresses' => [$recipientEmail]], + 'ReplyToAddresses' => [$senderEmail], + 'Source' => $senderEmail, + 'Message' => [ + 'Body' => [ + 'Text' => [ + 'Charset' => 'UTF-8', + 'Data' => $bodyText, + ], + ], + 'Subject' => [ + 'Charset' => 'UTF-8', + 'Data' => $subject, + ], + ], + ]); + } catch (AwsException $e) { + throw new Exception("Failed to send email: " . $e->getAwsErrorMessage()); + } + } + + /** + * Helper method to send a verification email. + * + * @param string $recipientEmail + * @param string $verificationCode + * @throws Exception if email sending fails. + */ + public function sendVerificationEmail(string $recipientEmail, string $verificationCode): void { + $subject = "Verify Your Email Address"; + $verificationLink = $this->config['app']['url'] . "/verify_email.php?code={$verificationCode}"; + $bodyText = "Please verify your email address by clicking the link below or by entering the code in your profile:\n\n"; + $bodyText .= "{$verificationLink}\n\nYour verification code is: {$verificationCode}\nThis code will expire in 15 minutes."; + $this->sendEmail($recipientEmail, $subject, $bodyText); + } +} diff --git a/classes/HeaderMeta.php b/classes/HeaderMeta.php index 14c7cbb..2efddd1 100644 --- a/classes/HeaderMeta.php +++ b/classes/HeaderMeta.php @@ -26,29 +26,29 @@ class HeaderMeta $this->config = $config; // detect if it is DJMixHosting\Mix, DJMixHosting\Genre, DJMixHosting\Mixshow, or DJMixHosting\DJ in $object if ($object instanceof Mix) { - $djs = $object->get_djs(); + $djs = $object->getDJs(); $djList = ""; foreach ($djs as $dj) { $djList .= $dj->getName() . ", "; } $djList = rtrim($djList, ", "); - $genres = $object->get_genres(); + $genres = $object->getGenres(); $genreNames = ""; $genreList = rtrim($genreNames, ", "); - $this->set_ogTitle($object->get_name()); - $this->set_ogDescription($object->get_description()); - $this->set_ogUrl($object->get_page_url()); - $this->set_ogImage($object->get_cover()); + $this->set_ogTitle($object->getName()); + $this->set_ogDescription($object->getDescription()); + $this->set_ogUrl($object->getPageUrl()); + $this->set_ogImage($object->getCover()); $this->set_ogType("music.song"); - $this->set_ogDurationSeconds($object->get_seconds()); + $this->set_ogDurationSeconds($object->getSeconds()); $this->set_ogMusician($djList); - $this->set_ogAudio($object->get_download_url()); + $this->set_ogAudio($object->getDownloadUrl()); $this->set_ogKeywords($genreList); - $this->set_ogCanonical($object->get_page_url()); + $this->set_ogCanonical($object->getPageUrl()); $this->set_ogRobot("index, follow"); $this->set_ogNoindex(""); } diff --git a/classes/Mix.php b/classes/Mix.php index 95fece0..2d00702 100644 --- a/classes/Mix.php +++ b/classes/Mix.php @@ -2,343 +2,277 @@ namespace DJMixHosting; +use DateTime; +use Exception; + class Mix { - - private $id = -1; - private $enabled = false; - private $name = ""; - private $slug = ""; - private $db = null; - private $description = ""; - private $cover = ""; - private $url = ""; - private $seconds = 0; - private $download_only = true; - private $djs = []; - private $genres = []; - private $recorded; - private $downloads = 0; - private $created; - private $updated; - private $playcount = 0; + private int $id = -1; + private bool $enabled = false; + private string $name = ""; + private string $slug = ""; + private $db; + private string $description = ""; + private string $cover = ""; + private string $url = ""; + private int $seconds = 0; + private bool $download_only = true; + private array $djs = []; + private array $genres = []; + private ?string $recorded = null; + private int $downloads = 0; + private ?string $created = null; + private ?string $updated = null; + private int $playcount = 0; private $tracklist = []; - private $loadDJs = true; - private $related_mixes = []; - private $duration = []; - private $mixshow = []; + private bool $loadDJs = true; + private array $related_mixes = []; + private array $duration = []; + private array $mixshow = []; - - public function __construct($value, $db, $loadDJs = true) + /** + * Construct a Mix object using either an ID or slug. + * + * @param mixed $value The mix identifier (ID or slug). + * @param mixed $db Database connection. + * @param bool $loadDJs Whether to load DJ objects. + */ + public function __construct($value, $db, bool $loadDJs = true) { $this->db = $db; - - // echo the type of value + $this->loadDJs = $loadDJs; if (ctype_digit((string)$value)) { $this->id = (int)$value; - return $this->load_by_id(); - + $loaded = $this->loadById(); } else { $this->slug = $value; - return $this->load_by_slug(); + $loaded = $this->loadBySlug(); + } + + if (!$loaded) { + throw new Exception("Mix not found."); } } - private function load_by_id(): bool + /** + * Loads mix data by its ID. + */ + private function loadById(): bool { - $mix = $this->get_mix_by_id(); - if ($mix && $mix['title'] != "") { - return $this->build_mix($mix); - } else { - return false; + $mix = $this->getMixById(); + if ($mix && !empty($mix['title'])) { + return $this->buildMix($mix); } + return false; } - private function get_mix_by_id() + /** + * Loads mix data by its slug. + */ + private function loadBySlug(): bool { - // Check if current user is admin - $isAdmin = (isset($_SESSION['user']) && isset($_SESSION['user']['role']) && $_SESSION['user']['role'] === 'admin'); - - if ($isAdmin) { - $stmt = $this->db->prepare("SELECT * FROM mix WHERE id = ?"); - } else { - // Only return approved mixes (pending = 0) for non-admins - $stmt = $this->db->prepare("SELECT * FROM mix WHERE id = ? AND pending = 0"); + $mix = $this->getMixBySlug(); + if ($mix && !empty($mix['title'])) { + return $this->buildMix($mix); } + return false; + } + + /** + * Retrieve mix data by ID. + */ + private function getMixById(): ?array + { + // If the current user is admin, show all mixes; + // Otherwise, only return mixes with pending = 0. + $isAdmin = isset($_SESSION['user']) && + isset($_SESSION['user']['role']) && + $_SESSION['user']['role'] === 'admin'; + $query = $isAdmin + ? "SELECT * FROM mix WHERE id = ?" + : "SELECT * FROM mix WHERE id = ? AND pending = 0"; + + $stmt = $this->db->prepare($query); $stmt->bind_param("i", $this->id); $stmt->execute(); $result = $stmt->get_result(); $mix = $result->fetch_assoc(); $stmt->close(); - return $mix; + return $mix ?: null; } + /** - * @param $mix - * @return true + * Retrieve mix data by slug. */ - private function build_mix($mix): bool + private function getMixBySlug(): ?array { - $this->id = $mix['id']; - $this->name = $mix['title']; - $this->slug = $mix['slug']; - $this->description = $mix['description']; - $this->cover = $this->legacyFix($mix['cover']); - $this->url = $this->legacyFix($mix['url']); - $this->seconds = $mix['seconds']; - $this->duration = $this->configure_duration(); - $this->download_only = $mix['mediaplayer']; - $this->recorded = $mix['recorded']; - $this->created = $mix['created']; - $this->updated = $mix['lastupdated']; - $this->enabled = $mix['pending']; + $isAdmin = isset($_SESSION['user']) && + isset($_SESSION['user']['role']) && + $_SESSION['user']['role'] === 'admin'; + $query = $isAdmin + ? "SELECT * FROM mix WHERE slug = ?" + : "SELECT * FROM mix WHERE slug = ? AND pending = 0"; + + $stmt = $this->db->prepare($query); + $stmt->bind_param("s", $this->slug); + $stmt->execute(); + $result = $stmt->get_result(); + $mix = $result->fetch_assoc(); + $stmt->close(); + return $mix ?: null; + } + + /** + * Build the mix object from database data. + */ + private function buildMix(array $mix): bool + { + $this->id = (int)$mix['id']; + $this->name = $mix['title'] ?? ""; + $this->slug = $mix['slug'] ?? ""; + $this->description = $mix['description'] ?? ""; + $this->cover = $this->legacyFix($mix['cover'] ?? ""); + $this->url = $this->legacyFix($mix['url'] ?? ""); + $this->seconds = (int)($mix['seconds'] ?? 0); + $this->duration = $this->configureDuration(); + $this->download_only = (bool)($mix['mediaplayer'] ?? true); + $this->recorded = $mix['recorded'] ?? null; + $this->created = $mix['created'] ?? null; + $this->updated = $mix['lastupdated'] ?? null; + $this->enabled = (bool)($mix['pending'] ?? false); + if ($this->loadDJs) { require_once 'DJ.php'; $this->djs[] = new DJ($mix['dj1'], $this->db); - if ($mix['dj2'] != null) { + if (!empty($mix['dj2'])) { $this->djs[] = new DJ($mix['dj2'], $this->db); } - if ($mix['dj3'] != null) { + if (!empty($mix['dj3'])) { $this->djs[] = new DJ($mix['dj3'], $this->db); } - $this->djs = array_filter($this->djs); } - $this->load_mix_meta(); - $this->tracklist = $this->evaluate_tracklist(); + $this->loadMixMeta(); + $this->tracklist = $this->evaluateTracklist(); return true; } - private function legacyFix(mixed $item) + /** + * Fix legacy URL paths. + */ + private function legacyFix(string $item): string { if (str_starts_with($item, "/djs/")) { return "https://cdn.utahsdjs.com" . substr($item, 4); - } else { - return $item; } + return $item; } - private function configure_duration(): array + /** + * Configure a formatted duration based on seconds. + */ + private function configureDuration(): array { $seconds = $this->seconds; $hours = floor($seconds / 3600); $minutes = floor(($seconds / 60) % 60); - $seconds = $seconds % 60; - - // for 't', we need to show it as 01:02:03 - if ($hours < 10) { - $hours0 = "0" . $hours; - } else { - $hours0 = $hours; - } - if ($minutes < 10) { - $minutes0 = "0" . $minutes; - } else { - $minutes0 = $minutes; - } - if ($seconds < 10) { - $seconds0 = "0" . $seconds; - } else { - $seconds0 = $seconds; - } - - // if hours is 0, we don't need to show it - $time = $hours > 0 ? $hours0 . ":" . $minutes0 . ":" . $seconds0 : $minutes0 . ":" . $seconds0; - - return ['h' => $hours, 'm' => $minutes, 's' => $seconds, 't' => $time, 'S' => $this->seconds]; + $secs = $seconds % 60; + $time = ($hours > 0) + ? sprintf("%02d:%02d:%02d", $hours, $minutes, $secs) + : sprintf("%02d:%02d", $minutes, $secs); + return [ + 'h' => $hours, + 'm' => $minutes, + 's' => $secs, + 't' => $time, + 'S' => $this->seconds + ]; } - private function load_mix_meta(): void + /** + * Load mix meta data. + */ + private function loadMixMeta(): void { - $stmt = $this->db->prepare("SELECT attribute,value FROM mix_meta WHERE mix_id = ?"); + $stmt = $this->db->prepare("SELECT attribute, value FROM mix_meta WHERE mix_id = ?"); $stmt->bind_param("i", $this->id); $stmt->execute(); $result = $stmt->get_result(); $meta = $result->fetch_all(MYSQLI_ASSOC); $stmt->close(); - foreach ($meta as $key => $value) { - if ($value['attribute'] == "genre") { - $this->genres[] = $value['value']; - unset($meta[$key]); + foreach ($meta as $entry) { + switch ($entry['attribute']) { + case "genre": + $this->genres[] = $entry['value']; + break; + case "related": + $this->related_mixes[] = $entry['value']; + break; + case "playcount": + $this->playcount = (int)$entry['value']; + break; + case "downloads": + $this->downloads = (int)$entry['value']; + break; + case "tracklist": + $this->tracklist = $entry['value']; + break; + case "mixshow": + $this->mixshow[] = $entry['value']; + break; + default: + // Handle additional meta attributes if needed. + break; } - if ($value['attribute'] == "related") { - $this->related_mixes[] = $value['value']; - unset($meta[$key]); - } - if ($value['attribute'] == "playcount") { - $this->playcount = $value['value']; - unset($meta[$key]); - } - if ($value['attribute'] == "downloads") { - $this->downloads = $value['value']; - unset($meta[$key]); - } - if ($value['attribute'] == "tracklist") { - $this->tracklist = $value['value']; - unset($meta[$key]); - } - if ($value['attribute'] == "mixshow") { - $this->mixshow[] = $value['value']; - unset($meta[$key]); - } - } - } - private function evaluate_tracklist() + /** + * Evaluate the tracklist data. + */ + private function evaluateTracklist() { if (empty($this->tracklist)) { return []; - } else { - // if the first item in the array is also an array, then return it - if (is_array($this->tracklist)) { - return $this->tracklist; - } else { - return explode("\n", (string)$this->tracklist); - } } - - } - - private function load_by_slug(): bool - { - $mix = $this->get_mix_by_slug(); - if ($mix) { - if ($mix['title'] != "") { - return $this->build_mix($mix); - } else { - return false; - } - } else { - return false; + if (is_array($this->tracklist)) { + return $this->tracklist; } + return explode("\n", (string)$this->tracklist); } + // Getter methods for mix properties. - private function get_mix_by_slug() + public function getId(): int { return $this->id; } + public function getName(): string { return $this->name; } + public function getSlug(): string { return $this->slug; } + public function getDescription(): string { return $this->description; } + public function getCover(): string { return $this->cover; } + public function getUrl(): string { return $this->url; } + public function getSeconds(): int { return $this->seconds; } + public function isDownloadOnly(): bool { return $this->download_only; } + public function getDJs(): array { return $this->djs; } + public function getGenres(): array { return $this->genres; } + public function getRecorded(): ?string { return $this->recorded; } + public function getDownloads(): int { return $this->downloads; } + public function getCreated(): ?string { return $this->created; } + public function getUpdated(): ?string { return $this->updated; } + public function getPlaycount(): int { return $this->playcount; } + public function getTracklist(): array { return $this->evaluateTracklist(); } + public function getRelatedMixes(): array { return $this->related_mixes; } + public function getDuration(): array { return $this->duration; } + public function getMixshow(): array { return $this->mixshow; } + + public function getDownloadUrl(): string { - // Check if current user is admin - $isAdmin = (isset($_SESSION['user']) && isset($_SESSION['user']['role']) && $_SESSION['user']['role'] === 'admin'); - - if ($isAdmin) { - $stmt = $this->db->prepare("SELECT * FROM mix WHERE slug = ?"); - } else { - $stmt = $this->db->prepare("SELECT * FROM mix WHERE slug = ? AND pending = 0"); - } - $stmt->bind_param("s", $this->slug); - $stmt->execute(); - $result = $stmt->get_result(); - $mix = $result->fetch_assoc(); - $stmt->close(); - return $mix; + return "https://beta.utahsdjs.com/mix/{$this->slug}/download"; } - public function get_recorded() + public function getPageUrl(): string { - return $this->recorded; + return "https://beta.utahsdjs.com/mix/{$this->slug}"; } - - public function get_created() - { - return $this->created; - } - - public function get_updated() - { - return $this->updated; - } - - public function get_img() - { - return $this->cover; - } - - public function get_djs() - { - return $this->djs; - } - - public function get_description() - { - return $this->description; - } - - public function get_tracklist(): array - { - return $this->tracklist; - } - - public function get_genres() - { - return $this->genres; - } - - public function get_seconds(): int - { - return $this->seconds; - } - - public function is_download_only(): bool - { - return $this->download_only; - } - - public function get_url(): string - { - return $this->url; - } - - public function get_cover() - { - return $this->cover; - } - - public function get_downloads(): int - { - return $this->downloads; - } - - public function get_plays(): int - { - return $this->playcount; - } - - public function get_id(): int - { - return $this->id; - } - - public function get_name(): string - { - return $this->name; - } - - public function get_slug(): string - { - return $this->slug; - } - - public function get_duration(): array - { - return $this->duration; - } - - public function get_mixshow(): array - { - return $this->mixshow; - } - - public function get_download_url() - { - return "https://beta.utahsdjs.com/mix/" . "$this->slug" . "/download"; - } - - public function get_page_url() - { - return "https://beta.utahsdjs.com/mix/" . "$this->slug"; - } - } diff --git a/classes/SessionManager.php b/classes/SessionManager.php new file mode 100644 index 0000000..d1f6a52 --- /dev/null +++ b/classes/SessionManager.php @@ -0,0 +1,39 @@ +file = $file; - $this->file_name = $file['name']; - $this->file_size = $file['size']; - $this->file_tmp = $file['tmp_name']; - $this->file_type = $file['type']; $this->config = $config; - $ext = explode('.', $file['name']); - $this->file_ext = strtolower(end($ext)); + $this->uploadDir = rtrim($config['uploads']['tmp_path'], '/') . '/'; $this->uuid = uniqid(); - + $this->fileExt = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); } - private function check_file_size(): bool + public function validate(): bool { - if ($this->file_size > $this->config['uploads']['max_file_size']){ - $this->errors[] = "File size is too large"; - return false; + if ($this->file['error'] !== UPLOAD_ERR_OK) { + $this->errors[] = "File upload error."; } - return true; - } - - private function check_file_extension(): bool - { - if (!in_array($this->file_ext, $this->extensions)){ - $this->errors[] = "Invalid file extension"; - return false; + if ($this->file['size'] > $this->config['uploads']['max_file_size']) { + $this->errors[] = "File is too large."; } - return true; - } - - private function check_file_exists(): bool - { - if (file_exists($this->upload_dir . $this->file_name)){ - $this->errors[] = "File already exists"; - return false; + if (!in_array($this->fileExt, $this->config['uploads']['allowed_file_types'])) { + $this->errors[] = "File type not allowed."; } - return true; + if (!in_array($this->file['type'], $this->config['uploads']['allowed_mime_type'])) { + $this->errors[] = "MIME type not allowed."; + } + return empty($this->errors); } - private function move_file(): bool + public function getErrors(): array { - if (move_uploaded_file($this->file_tmp, $this->upload_dir . $this->uuid)){ - $this->file_path = $this->upload_dir . $this->uuid; + return $this->errors; + } + + public function moveFile(): bool + { + $destination = $this->uploadDir . $this->uuid . "." . $this->fileExt; + if (move_uploaded_file($this->file['tmp_name'], $destination)) { + $this->localPath = $destination; return true; } + $this->errors[] = "Failed to move uploaded file."; return false; } - public function dump_all() + public function process(): array { - $array = array( - "file" => $this->file, - "file_name" => $this->file_name, - "file_size" => $this->file_size, - "file_tmp" => $this->file_tmp, - "file_type" => $this->file_type, - "file_ext" => $this->file_ext, - "file_path" => $this->file_path, - "extensions" => $this->extensions, - "upload_dir" => $this->upload_dir, - "errors" => $this->errors, - "ok" => $this->ok, - "uuid" => $this->uuid - ); + // Assuming moveFile() has been called + $uploadTask = [ + 'original_name' => $this->file['name'], + 'local_path' => $this->localPath, + 'size' => $this->file['size'], + 'ext' => $this->fileExt, + ]; + + if ($this->fileExt === "mp3") { + $escapedFile = escapeshellarg($this->localPath); + $artist = trim(shell_exec("eyed3 --query='%a%' $escapedFile")); + $title = trim(shell_exec("eyed3 --query='%t%' $escapedFile")); + $duration = trim(shell_exec("mp3info -p \"%S\" $escapedFile")); + + $uploadTask['file_type'] = 'mp3'; + $uploadTask['metadata'] = [ + 'artist' => $artist, + 'title' => $title, + 'duration' => $duration, + ]; + $uploadTask['mediaplayer'] = 0; + } elseif ($this->fileExt === "zip") { + $zip = new \ZipArchive; + if ($zip->open($this->localPath) === true) { + $totalDuration = 0; + $tracklist = []; + for ($i = 0; $i < $zip->numFiles; $i++) { + $entryName = $zip->getNameIndex($i); + $entryExt = strtolower(pathinfo($entryName, PATHINFO_EXTENSION)); + if ($entryExt === "mp3") { + $tempDir = $this->uploadDir . uniqid('zip_'); + mkdir($tempDir); + $tempFilePath = $tempDir . '/' . basename($entryName); + $zip->extractTo($tempDir, $entryName); + $escapedFile = escapeshellarg($tempFilePath); + $title = trim(shell_exec("eyed3 --query='%t%' $escapedFile")); + $duration = trim(shell_exec("mp3info -p \"%S\" $escapedFile")); + $tracklist[] = $title ?: basename($entryName); + $totalDuration += (int)$duration; + unlink($tempFilePath); + rmdir($tempDir); + } + } + $zip->close(); + $uploadTask['file_type'] = 'zip'; + $uploadTask['metadata'] = [ + 'tracklist' => $tracklist, + 'total_duration' => $totalDuration, + ]; + $uploadTask['mediaplayer'] = 1; + } else { + $this->errors[] = "Failed to open ZIP file."; + } + } else { + $this->errors[] = "Unsupported file type."; + } + + return $uploadTask; } + public function uploadToCDN(CDN $cdn): string + { + // Create a remote path – e.g., under a temp folder with a unique name + $remotePath = "temp/mixes/" . uniqid() . "_" . basename($this->localPath); + $mimeType = ($this->fileExt === 'mp3') ? 'audio/mpeg' : 'application/zip'; + + $cdn->uploadFile($this->localPath, $remotePath, $mimeType); + return $remotePath; + } } diff --git a/classes/User.php b/classes/User.php index 67343b0..048d621 100644 --- a/classes/User.php +++ b/classes/User.php @@ -2,13 +2,19 @@ namespace DJMixHosting; +use DateTime; +use Exception; use Random\RandomException; +use Aws\Ses\SesClient; +use Aws\Exception\AwsException; -Class User{ +class User { private $db; private $id; private $username; + private $firstName; + private $lastName; private $email; private $location; private $bio; @@ -16,42 +22,83 @@ Class User{ private $updated; private $verified; private $role; - private $img; + + private $img = ""; private $api_key; - public function __construct($db){ + public function __construct($db, $id = null) { $this->db = $db; + if ($id) { + $this->loadUserById($id); + } } /** - * @throws RandomException + * Load user data from the database by id. */ - public function newUser($username, $password, $email){ - if ($this->check_existing_user($username, $email)){ - throw new RandomException("User already exists"); + private function loadUserById($id) { + $stmt = $this->db->prepare("SELECT * FROM users WHERE id = ?"); + $stmt->bind_param("i", $id); + $stmt->execute(); + $user_data = $stmt->get_result()->fetch_assoc(); + $stmt->close(); + + if ($user_data) { + $this->id = $user_data['id']; + $this->username = $user_data['username']; + $this->firstName = $user_data['firstName']; + $this->lastName = $user_data['lastName']; + $this->email = $user_data['email']; + $this->verified = $user_data['emailVerified']; + $this->img = $user_data['img']; + $this->api_key = $user_data['apiKey']; + $this->created = $user_data['created']; + $this->updated = $user_data['lastupdated']; + $this->role = $user_data['isAdmin'] ? 'admin' : 'user'; + + // These fields are not in your table; assign defaults or remove them. + $this->location = ""; + $this->bio = ""; + } + } + + /** + * Register a new user. + * + * @throws RandomException if the user already exists. + */ + public function newUser(string $username, string $password, string $email, string $firstName, string $lastName): int { + if ($this->check_existing_user($username, $email)) { + throw new \Random\RandomException("User already exists"); } $this->username = $username; $this->email = $email; - $password2 = password_hash($password, PASSWORD_DEFAULT); - $this->password = $password2; + $this->firstName = $firstName; + $this->lastName = $lastName; + $password_hashed = password_hash($password, PASSWORD_DEFAULT); - $this->location = ""; - $this->bio = ""; - $this->created = date('Y-m-d H:i:s'); - $this->updated = date('Y-m-d H:i:s'); - $this->verified = 0; - $this->role = "user"; - $this->img = ""; - $this->api_key = bin2hex(random_bytes(32)); + // Set default values for optional fields. + $this->location = ""; + $this->bio = ""; + $this->created = date('Y-m-d H:i:s'); + $this->updated = date('Y-m-d H:i:s'); + $this->verified = 0; + $this->role = "user"; + $this->img = ""; + $this->api_key = bin2hex(random_bytes(32)); - $stmt = $this->db->prepare("INSERT INTO users (username, password, email, img) VALUES (?, ?, ?, ?)"); - $stmt->bind_param("ssss", $this->username, $this->password, $this->email, $this->img); + $stmt = $this->db->prepare("INSERT INTO users (username, password, email, firstName, lastName, img, emailVerified) VALUES (?, ?, ?, ?, ?, '', 0)"); + $stmt->bind_param("sssss", $this->username, $password_hashed, $this->email, $this->firstName, $this->lastName); $stmt->execute(); + $userId = $stmt->insert_id; $stmt->close(); + $this->id = $userId; + return $userId; } - private function check_existing_user($username, $email){ + + private function check_existing_user($username, $email) { $stmt = $this->db->prepare("SELECT * FROM users WHERE username = ? OR email = ?"); $stmt->bind_param("ss", $username, $email); $stmt->execute(); @@ -61,8 +108,13 @@ Class User{ return $user; } - public function login($email, $password) - { + /** + * Login a user by email and password. + * + * Returns the user data array if successful. In case of failure, + * a string error message is returned. + */ + public function login($email, $password) { // Retrieve user record by email $stmt = $this->db->prepare("SELECT * FROM users WHERE email = ?"); $stmt->bind_param("s", $email); @@ -78,10 +130,10 @@ Class User{ $attempt_data = $stmt->get_result()->fetch_assoc(); $stmt->close(); - $current_time = new \DateTime(); + $current_time = new DateTime(); if ($attempt_data && !empty($attempt_data['lockout_until'])) { - $lockout_until = new \DateTime($attempt_data['lockout_until']); + $lockout_until = new DateTime($attempt_data['lockout_until']); if ($current_time < $lockout_until) { return "Account locked until " . $lockout_until->format('Y-m-d H:i:s') . ". Please try again later."; } @@ -95,15 +147,10 @@ Class User{ // Verify the password using password_verify if (password_verify($password, $user_data['password'])) { - // Successful login – clear login attempts and set session variables + // Successful login – clear login attempts. $this->resetLoginAttempts($email); - $_SESSION['user'] = [ - 'id' => $user_data['id'], - 'email' => $user_data['email'], - 'username' => $user_data['username'], - 'role' => $user_data['isAdmin'] ? 'admin' : 'user' - ]; - return true; + // Return the user data for further session handling + return $user_data; } else { $attempts = $this->updateFailedAttempt($email); return "Invalid email or password. Attempt $attempts of 3."; @@ -115,8 +162,7 @@ Class User{ * If attempts reach 3, set a lockout that doubles each time. * Returns the current number of attempts. */ - private function updateFailedAttempt($email) - { + private function updateFailedAttempt($email) { // Check for an existing record $stmt = $this->db->prepare("SELECT * FROM login_attempts WHERE email = ?"); $stmt->bind_param("s", $email); @@ -124,7 +170,7 @@ Class User{ $record = $stmt->get_result()->fetch_assoc(); $stmt->close(); - $current_time = new \DateTime(); + $current_time = new DateTime(); if ($record) { $attempts = $record['attempts'] + 1; @@ -165,13 +211,186 @@ Class User{ /** * Reset the login_attempts record for the given email. */ - private function resetLoginAttempts($email) - { + private function resetLoginAttempts($email) { $stmt = $this->db->prepare("DELETE FROM login_attempts WHERE email = ?"); $stmt->bind_param("s", $email); $stmt->execute(); $stmt->close(); } + /** + * Update the user's email address. + * + * @param string $newEmail + * @param array $config Configuration array for AWS SES and app settings. + * @return string Success message. + * @throws \Exception on validation or email-sending failure. + */ + public function updateEmail(string $newEmail, array $config): string { + $newEmail = filter_var($newEmail, FILTER_VALIDATE_EMAIL); + if (!$newEmail) { + throw new \Exception("Invalid email format."); + } -} \ No newline at end of file + // Update email and mark as unverified. + $stmt = $this->db->prepare("UPDATE users SET email = ?, emailVerified = 0 WHERE id = ?"); + $stmt->bind_param("si", $newEmail, $this->id); + $stmt->execute(); + $stmt->close(); + + // Generate verification code and expiry (15 minutes from now) + $verification_code = bin2hex(random_bytes(16)); + $expires_at = date("Y-m-d H:i:s", strtotime("+15 minutes")); + + // Store the verification record. + $stmt = $this->db->prepare("REPLACE INTO email_verifications (user_id, email, verification_code, expires_at) VALUES (?, ?, ?, ?)"); + $stmt->bind_param("isss", $this->id, $newEmail, $verification_code, $expires_at); + $stmt->execute(); + $stmt->close(); + + // Use the new Email class to send the verification email. + $emailObj = new Email($config); + $emailObj->sendVerificationEmail($newEmail, $verification_code); + + // Update the class properties. + $this->email = $newEmail; + $this->verified = 0; + return "Email updated. A verification email has been sent to your new address."; + } + + public function updateName($firstName, $lastName) { + // Update the user's name. + $stmt = $this->db->prepare("UPDATE users SET firstName = ?, lastName = ? WHERE id = ?"); + $stmt->bind_param("ssi", $firstName, $lastName, $this->id); + if (!$stmt->execute()) { + $stmt->close(); + throw new Exception("Failed to update name. Please try again."); + } + $stmt->close(); + + // Optionally update class properties. + $this->firstName = $firstName; + $this->lastName = $lastName; + return "Name updated successfully."; + } + + public function updatePassword($currentPassword, $newPassword, $confirmPassword) { + // Retrieve the current password hash. + $stmt = $this->db->prepare("SELECT password FROM users WHERE id = ?"); + $stmt->bind_param("i", $this->id); + $stmt->execute(); + $userData = $stmt->get_result()->fetch_assoc(); + $stmt->close(); + + if (!$userData || !password_verify($currentPassword, $userData['password'])) { + throw new Exception("Current password is incorrect."); + } + + if ($newPassword !== $confirmPassword) { + throw new Exception("New password and confirmation do not match."); + } + + // Validate the new password. + $pattern = '/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,32}$/'; + if (!preg_match($pattern, $newPassword)) { + throw new Exception("New password must be 8-32 characters and include at least one uppercase letter, one lowercase letter, one number, and one symbol."); + } + + $hashed_new_password = password_hash($newPassword, PASSWORD_DEFAULT); + $stmt = $this->db->prepare("UPDATE users SET password = ? WHERE id = ?"); + $stmt->bind_param("si", $hashed_new_password, $this->id); + if (!$stmt->execute()) { + $stmt->close(); + throw new Exception("Failed to update password. Please try again."); + } + $stmt->close(); + return "Password updated successfully."; + } + + public function updateUsername($newUsername) { + // Validate username format. + if (!preg_match('/^[a-zA-Z0-9_]{3,25}$/', $newUsername)) { + throw new Exception("Invalid username format."); + } + + // Check if the new username already exists for another user. + $stmt = $this->db->prepare("SELECT id FROM users WHERE username = ? AND id != ?"); + $stmt->bind_param("si", $newUsername, $this->id); + $stmt->execute(); + $result = $stmt->get_result(); + if ($result->num_rows > 0) { + $stmt->close(); + throw new Exception("Username already taken."); + } + $stmt->close(); + + // Update the username. + $stmt = $this->db->prepare("UPDATE users SET username = ? WHERE id = ?"); + $stmt->bind_param("si", $newUsername, $this->id); + $stmt->execute(); + $stmt->close(); + + $this->username = $newUsername; + return "Username updated successfully."; + } + + /** + * Verify the user's email using the provided verification code. + * + * @param string $verification_code The code submitted by the user. + * @return string Success message. + * @throws \Exception If the code is invalid or expired. + */ + public function verifyEmail(string $verification_code): string { + // Look up the verification record for this user and code + $stmt = $this->db->prepare("SELECT * FROM email_verifications WHERE user_id = ? AND verification_code = ?"); + $stmt->bind_param("is", $this->id, $verification_code); + $stmt->execute(); + $result = $stmt->get_result(); + $record = $result->fetch_assoc(); + $stmt->close(); + + if (!$record) { + throw new \Exception("Invalid verification code."); + } + + // Check if the verification code has expired + $current_time = new \DateTime(); + $expires_at = new \DateTime($record['expires_at']); + if ($current_time > $expires_at) { + throw new \Exception("Verification code has expired. Please request a new one."); + } + + // Update the user's record to mark the email as verified + $stmt = $this->db->prepare("UPDATE users SET emailVerified = 1 WHERE id = ?"); + $stmt->bind_param("i", $this->id); + $stmt->execute(); + $stmt->close(); + + // Remove the verification record to clean up + $stmt = $this->db->prepare("DELETE FROM email_verifications WHERE user_id = ?"); + $stmt->bind_param("i", $this->id); + $stmt->execute(); + $stmt->close(); + + // Update the object property + $this->verified = 1; + + return "Email verified successfully."; + } + + // Getter methods + public function getId() { return $this->id; } + public function getUsername() { return $this->username; } + public function getFirstName() { return $this->firstName; } + public function getLastName() { return $this->lastName; } + public function getEmail() { return $this->email; } + public function getLocation() { return $this->location; } + public function getBio() { return $this->bio; } + public function getCreated() { return $this->created; } + public function getUpdated() { return $this->updated; } + public function getVerified() { return $this->verified; } + public function getRole() { return $this->role; } + public function getImg() { return $this->img; } + public function getApiKey() { return $this->api_key; } +} diff --git a/composer.json b/composer.json index 7b6d363..97366ec 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "utahsdjs/utahsdjs2025", "description": "description", "minimum-stability": "dev", - "version": "0.0.1", + "version": "0.0.16", "license": "proprietary", "authors": [ { @@ -11,12 +11,13 @@ } ], "require": { - "php": ">=8.2.0", - "yosymfony/toml": "*", - "ext-mysqli": "*", + "aws/aws-sdk-php": ">=3.339.15", "ext-curl": "*", - "phpunit/phpunit": ">8.5.1.0", - "aws/aws-sdk-php": "*" + "ext-mysqli": "*", + "php": ">=8.2.0", + "phpunit/phpunit": ">=11", + "yosymfony/toml": "*", + "ext-zip": "*" }, "autoload": { "psr-4": { diff --git a/composer.lock b/composer.lock index c561621..5e74b18 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,566 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c891b4f6d2749c8df8c478b2acaf7679", + "content-hash": "adb0fe283e0b70b4602662fb7ea5bce8", "packages": [ + { + "name": "aws/aws-crt-php", + "version": "v1.2.7", + "source": { + "type": "git", + "url": "https://github.com/awslabs/aws-crt-php.git", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "AWS SDK Common Runtime Team", + "email": "aws-sdk-common-runtime@amazon.com" + } + ], + "description": "AWS Common Runtime for PHP", + "homepage": "https://github.com/awslabs/aws-crt-php", + "keywords": [ + "amazon", + "aws", + "crt", + "sdk" + ], + "support": { + "issues": "https://github.com/awslabs/aws-crt-php/issues", + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" + }, + "time": "2024-10-18T22:15:13+00:00" + }, + { + "name": "aws/aws-sdk-php", + "version": "3.339.15", + "source": { + "type": "git", + "url": "https://github.com/aws/aws-sdk-php.git", + "reference": "46ef2d3734ba8358966af80e4ac181633bd03692" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/46ef2d3734ba8358966af80e4ac181633bd03692", + "reference": "46ef2d3734ba8358966af80e4ac181633bd03692", + "shasum": "" + }, + "require": { + "aws/aws-crt-php": "^1.2.3", + "ext-json": "*", + "ext-pcre": "*", + "ext-simplexml": "*", + "guzzlehttp/guzzle": "^7.4.5", + "guzzlehttp/promises": "^2.0", + "guzzlehttp/psr7": "^2.4.5", + "mtdowling/jmespath.php": "^2.8.0", + "php": ">=8.1", + "psr/http-message": "^2.0" + }, + "require-dev": { + "andrewsville/php-token-reflection": "^1.4", + "aws/aws-php-sns-message-validator": "~1.0", + "behat/behat": "~3.0", + "composer/composer": "^2.7.8", + "dms/phpunit-arraysubset-asserts": "^0.4.0", + "doctrine/cache": "~1.4", + "ext-dom": "*", + "ext-openssl": "*", + "ext-pcntl": "*", + "ext-sockets": "*", + "phpunit/phpunit": "^5.6.3 || ^8.5 || ^9.5", + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "symfony/filesystem": "^v6.4.0 || ^v7.1.0", + "yoast/phpunit-polyfills": "^2.0" + }, + "suggest": { + "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", + "doctrine/cache": "To use the DoctrineCacheAdapter", + "ext-curl": "To send requests using cURL", + "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-sockets": "To use client-side monitoring" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Aws\\": "src/" + }, + "exclude-from-classmap": [ + "src/data/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Amazon Web Services", + "homepage": "http://aws.amazon.com" + } + ], + "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", + "homepage": "http://aws.amazon.com/sdkforphp", + "keywords": [ + "amazon", + "aws", + "cloud", + "dynamodb", + "ec2", + "glacier", + "s3", + "sdk" + ], + "support": { + "forum": "https://github.com/aws/aws-sdk-php/discussions", + "issues": "https://github.com/aws/aws-sdk-php/issues", + "source": "https://github.com/aws/aws-sdk-php/tree/3.339.15" + }, + "time": "2025-02-17T19:07:50+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.9.x-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "41f5ce75250c5c3af5a4bb2410143ddfede8127c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41f5ce75250c5c3af5a4bb2410143ddfede8127c", + "reference": "41f5ce75250c5c3af5a4bb2410143ddfede8127c", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5.3 || ^2.0.3", + "guzzlehttp/psr7": "^2.7.0", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "ext-curl": "*", + "guzzle/client-integration-tests": "3.0.2", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "default-branch": true, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.9" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2025-02-03T10:53:14+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "2.0.x-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "90c5be4a7c8374e8079c06232b07eb6e5cbbfdf3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/90c5be4a7c8374e8079c06232b07eb6e5cbbfdf3", + "reference": "90c5be4a7c8374e8079c06232b07eb6e5cbbfdf3", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "default-branch": true, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/2.0" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2025-02-03T10:48:03+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.7.x-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "ca06f23f35cf0b70a6f56d3d95c51bbc1062fade" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/ca06f23f35cf0b70a6f56d3d95c51bbc1062fade", + "reference": "ca06f23f35cf0b70a6f56d3d95c51bbc1062fade", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.39 || ^9.6.20" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "default-branch": true, + "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.7" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2025-02-03T10:49:42+00:00" + }, + { + "name": "mtdowling/jmespath.php", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/jmespath/jmespath.php.git", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "reference": "a2a865e05d5f420b50cc2f85bb78d565db12a6bc", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "symfony/polyfill-mbstring": "^1.17" + }, + "require-dev": { + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.33" + }, + "default-branch": true, + "bin": [ + "bin/jp.php" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.8-dev" + } + }, + "autoload": { + "files": [ + "src/JmesPath.php" + ], + "psr-4": { + "JmesPath\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Declaratively specify how to extract elements from a JSON document", + "keywords": [ + "json", + "jsonpath" + ], + "support": { + "issues": "https://github.com/jmespath/jmespath.php/issues", + "source": "https://github.com/jmespath/jmespath.php/tree/2.8.0" + }, + "time": "2024-09-04T18:46:31+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.x-dev", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "2f5294676c802a62b0549f6bc8983f14294ce369" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/2f5294676c802a62b0549f6bc8983f14294ce369", - "reference": "2f5294676c802a62b0549f6bc8983f14294ce369", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { @@ -57,7 +603,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -65,20 +611,20 @@ "type": "tidelift" } ], - "time": "2024-02-10T11:10:03+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", - "version": "dev-master", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c5ee33df86c06b3278c670f64273b1ba768a0744" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c5ee33df86c06b3278c670f64273b1ba768a0744", - "reference": "c5ee33df86c06b3278c670f64273b1ba768a0744", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { @@ -91,7 +637,6 @@ "ircmaxell/php-yacc": "^0.0.7", "phpunit/phpunit": "^9.0" }, - "default-branch": true, "bin": [ "bin/php-parse" ], @@ -122,9 +667,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/master" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2024-04-19T12:04:10+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "phar-io/manifest", @@ -247,45 +792,44 @@ }, { "name": "phpunit/php-code-coverage", - "version": "dev-main", + "version": "11.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "cafa435d750d52e5e7c9c671341483d12d260c45" + "reference": "532c90222daa08133040389059739a3fb23ff726" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cafa435d750d52e5e7c9c671341483d12d260c45", - "reference": "cafa435d750d52e5e7c9c671341483d12d260c45", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/532c90222daa08133040389059739a3fb23ff726", + "reference": "532c90222daa08133040389059739a3fb23ff726", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.0", + "nikic/php-parser": "^5.4.0", "php": ">=8.2", - "phpunit/php-file-iterator": "^5.0", - "phpunit/php-text-template": "^4.0", - "sebastian/code-unit-reverse-lookup": "^4.0", - "sebastian/complexity": "^4.0", - "sebastian/environment": "^7.0", - "sebastian/lines-of-code": "^3.0", - "sebastian/version": "^5.0", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.5.2" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "11.0-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -314,7 +858,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/main" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0" }, "funding": [ { @@ -322,33 +866,32 @@ "type": "github" } ], - "time": "2024-03-22T13:49:53+00:00" + "time": "2025-02-08T08:59:40+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "dev-main", + "version": "5.1.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "17bc6a26ceb3b67795b077c30f64eb34ac567940" + "reference": "81c1a3b5618745429a4cddb617811b1a67844756" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/17bc6a26ceb3b67795b077c30f64eb34ac567940", - "reference": "17bc6a26ceb3b67795b077c30f64eb34ac567940", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/81c1a3b5618745429a4cddb617811b1a67844756", + "reference": "81c1a3b5618745429a4cddb617811b1a67844756", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -376,7 +919,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/main" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1" }, "funding": [ { @@ -384,20 +927,20 @@ "type": "github" } ], - "time": "2024-03-22T13:50:31+00:00" + "time": "2025-01-15T13:38:51+00:00" }, { "name": "phpunit/php-invoker", - "version": "dev-main", + "version": "5.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "ae870f44c9f8c65db178de7dcb206117669d85c8" + "reference": "4bb10b0973f1ae03c455703cbce4b945a2823eb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/ae870f44c9f8c65db178de7dcb206117669d85c8", - "reference": "ae870f44c9f8c65db178de7dcb206117669d85c8", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/4bb10b0973f1ae03c455703cbce4b945a2823eb1", + "reference": "4bb10b0973f1ae03c455703cbce4b945a2823eb1", "shasum": "" }, "require": { @@ -405,12 +948,11 @@ }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "suggest": { "ext-pcntl": "*" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -441,7 +983,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/main" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0" }, "funding": [ { @@ -449,29 +991,28 @@ "type": "github" } ], - "time": "2024-03-22T13:51:25+00:00" + "time": "2025-01-16T08:01:27+00:00" }, { "name": "phpunit/php-text-template", - "version": "dev-main", + "version": "4.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "12a457719941dff82067d119e39767cb3d63f515" + "reference": "824e778d57ef78e2746ee5455a3ed5919b6dde83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/12a457719941dff82067d119e39767cb3d63f515", - "reference": "12a457719941dff82067d119e39767cb3d63f515", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/824e778d57ef78e2746ee5455a3ed5919b6dde83", + "reference": "824e778d57ef78e2746ee5455a3ed5919b6dde83", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -502,7 +1043,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/main" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0" }, "funding": [ { @@ -510,29 +1051,28 @@ "type": "github" } ], - "time": "2024-03-22T13:51:58+00:00" + "time": "2025-01-16T08:06:04+00:00" }, { "name": "phpunit/php-timer", - "version": "dev-main", + "version": "7.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e8331ed6a4f21053ac7ba41f337ed5ef447c6378" + "reference": "9abd4039e4c05215137c49b6e81ba248aeaafcd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e8331ed6a4f21053ac7ba41f337ed5ef447c6378", - "reference": "e8331ed6a4f21053ac7ba41f337ed5ef447c6378", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/9abd4039e4c05215137c49b6e81ba248aeaafcd4", + "reference": "9abd4039e4c05215137c49b6e81ba248aeaafcd4", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -563,7 +1103,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/main" + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0" }, "funding": [ { @@ -571,20 +1111,20 @@ "type": "github" } ], - "time": "2024-03-22T13:52:26+00:00" + "time": "2025-01-16T08:08:47+00:00" }, { "name": "phpunit/phpunit", - "version": "dev-main", + "version": "11.5.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "450ca7684a02adb4eed46c4e9f64ef57fc7ac57b" + "reference": "c9bd61aab12f0fc5e82ecfe621ff518a1d1f1049" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/450ca7684a02adb4eed46c4e9f64ef57fc7ac57b", - "reference": "450ca7684a02adb4eed46c4e9f64ef57fc7ac57b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c9bd61aab12f0fc5e82ecfe621ff518a1d1f1049", + "reference": "c9bd61aab12f0fc5e82ecfe621ff518a1d1f1049", "shasum": "" }, "require": { @@ -594,37 +1134,37 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0", - "phpunit/php-file-iterator": "^5.0", - "phpunit/php-invoker": "^5.0", - "phpunit/php-text-template": "^4.0", - "phpunit/php-timer": "^7.0", - "sebastian/cli-parser": "^3.0", - "sebastian/code-unit": "^3.0", - "sebastian/comparator": "^6.0", - "sebastian/diff": "^6.0", - "sebastian/environment": "^7.0", - "sebastian/exporter": "^6.0", - "sebastian/global-state": "^7.0", - "sebastian/object-enumerator": "^6.0", - "sebastian/type": "^5.0", - "sebastian/version": "^5.0" + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" }, - "default-branch": true, "bin": [ "phpunit" ], "type": "library", "extra": { "branch-alias": { - "dev-main": "11.2-dev" + "dev-main": "11.5-dev" } }, "autoload": { @@ -656,7 +1196,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/main" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.8" }, "funding": [ { @@ -672,29 +1212,234 @@ "type": "tidelift" } ], - "time": "2024-05-14T14:32:54+00:00" + "time": "2025-02-18T06:26:59+00:00" }, { - "name": "sebastian/cli-parser", - "version": "dev-main", + "name": "psr/http-client", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "47c93ee55891788203dcb8efefa5abe46472266b" + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/47c93ee55891788203dcb8efefa5abe46472266b", - "reference": "47c93ee55891788203dcb8efefa5abe46472266b", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.x-dev", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "02c40090ebd250b0147747dc93e9ed81fcab0bbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/02c40090ebd250b0147747dc93e9ed81fcab0bbb", + "reference": "02c40090ebd250b0147747dc93e9ed81fcab0bbb", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -722,7 +1467,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/main" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0" }, "funding": [ { @@ -730,7 +1475,7 @@ "type": "github" } ], - "time": "2024-04-04T08:53:05+00:00" + "time": "2025-01-16T08:11:18+00:00" }, { "name": "sebastian/code-unit", @@ -738,19 +1483,19 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "2a4919d2c7eb2e17379ea1e878fc8c176042ecf4" + "reference": "1f56f951e080c0353ee13ed8e5a8e900b9e7a6b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/2a4919d2c7eb2e17379ea1e878fc8c176042ecf4", - "reference": "2a4919d2c7eb2e17379ea1e878fc8c176042ecf4", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1f56f951e080c0353ee13ed8e5a8e900b9e7a6b7", + "reference": "1f56f951e080c0353ee13ed8e5a8e900b9e7a6b7", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.5" }, "default-branch": true, "type": "library", @@ -788,7 +1533,7 @@ "type": "github" } ], - "time": "2024-04-03T07:55:50+00:00" + "time": "2025-01-01T09:30:51+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -796,19 +1541,19 @@ "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1a47d8a852f23d8320d5f401384260bea8b0b90b" + "reference": "1b040bebc0fc06a6e6f65cd3079de9ba0dbfaef1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1a47d8a852f23d8320d5f401384260bea8b0b90b", - "reference": "1a47d8a852f23d8320d5f401384260bea8b0b90b", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1b040bebc0fc06a6e6f65cd3079de9ba0dbfaef1", + "reference": "1b040bebc0fc06a6e6f65cd3079de9ba0dbfaef1", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "default-branch": true, "type": "library", @@ -845,20 +1590,20 @@ "type": "github" } ], - "time": "2024-03-22T13:41:37+00:00" + "time": "2025-01-01T09:31:42+00:00" }, { "name": "sebastian/comparator", - "version": "dev-main", + "version": "6.3.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "332f4a7ab51027ff603d1d8802e67dd76d055690" + "reference": "cbcaecfa4ab41974fccd3f7798870cf47221c477" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/332f4a7ab51027ff603d1d8802e67dd76d055690", - "reference": "332f4a7ab51027ff603d1d8802e67dd76d055690", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/cbcaecfa4ab41974fccd3f7798870cf47221c477", + "reference": "cbcaecfa4ab41974fccd3f7798870cf47221c477", "shasum": "" }, "require": { @@ -869,13 +1614,15 @@ "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -915,7 +1662,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/main" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3" }, "funding": [ { @@ -923,20 +1670,20 @@ "type": "github" } ], - "time": "2024-03-22T13:42:26+00:00" + "time": "2025-01-16T08:17:12+00:00" }, { "name": "sebastian/complexity", - "version": "dev-main", + "version": "4.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "6046d9b01615fd134232aaca1324390f89f5532c" + "reference": "217eb6229de259b43e2ff3dd82ef3a759f31af9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/6046d9b01615fd134232aaca1324390f89f5532c", - "reference": "6046d9b01615fd134232aaca1324390f89f5532c", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/217eb6229de259b43e2ff3dd82ef3a759f31af9d", + "reference": "217eb6229de259b43e2ff3dd82ef3a759f31af9d", "shasum": "" }, "require": { @@ -944,9 +1691,8 @@ "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -974,7 +1720,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/main" + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0" }, "funding": [ { @@ -982,30 +1728,29 @@ "type": "github" } ], - "time": "2024-03-22T13:42:56+00:00" + "time": "2025-01-16T08:18:27+00:00" }, { "name": "sebastian/diff", - "version": "dev-main", + "version": "6.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "367ce918f5d43d068889655f9720e2baf3325d62" + "reference": "689a62c19e700d71d8d1a82550cb4f090744dcb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/367ce918f5d43d068889655f9720e2baf3325d62", - "reference": "367ce918f5d43d068889655f9720e2baf3325d62", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/689a62c19e700d71d8d1a82550cb4f090744dcb0", + "reference": "689a62c19e700d71d8d1a82550cb4f090744dcb0", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0", + "phpunit/phpunit": "^11.3", "symfony/process": "^4.2 || ^5" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1042,7 +1787,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/main" + "source": "https://github.com/sebastianbergmann/diff/tree/6.0" }, "funding": [ { @@ -1050,32 +1795,31 @@ "type": "github" } ], - "time": "2024-03-22T13:44:09+00:00" + "time": "2025-01-16T08:21:04+00:00" }, { "name": "sebastian/environment", - "version": "dev-main", + "version": "7.2.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "ff8e9b0dc10315e13f3a7951eec6b227e66997e7" + "reference": "3af4c9f584519cbb3667b5e9b3b14baa0047ecab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/ff8e9b0dc10315e13f3a7951eec6b227e66997e7", - "reference": "ff8e9b0dc10315e13f3a7951eec6b227e66997e7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/3af4c9f584519cbb3667b5e9b3b14baa0047ecab", + "reference": "3af4c9f584519cbb3667b5e9b3b14baa0047ecab", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, "suggest": { "ext-posix": "*" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1107,7 +1851,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/main" + "source": "https://github.com/sebastianbergmann/environment/tree/7.2" }, "funding": [ { @@ -1115,20 +1859,20 @@ "type": "github" } ], - "time": "2024-03-23T13:07:37+00:00" + "time": "2025-01-16T08:26:24+00:00" }, { "name": "sebastian/exporter", - "version": "dev-main", + "version": "6.3.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "b9c7cad904c5c2596beb29ceb8fb794be3edc539" + "reference": "20a3d69003af1cd933e9b6d1c584e948885a29e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/b9c7cad904c5c2596beb29ceb8fb794be3edc539", - "reference": "b9c7cad904c5c2596beb29ceb8fb794be3edc539", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/20a3d69003af1cd933e9b6d1c584e948885a29e1", + "reference": "20a3d69003af1cd933e9b6d1c584e948885a29e1", "shasum": "" }, "require": { @@ -1137,13 +1881,12 @@ "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "6.3-dev" } }, "autoload": { @@ -1186,7 +1929,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/main" + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3" }, "funding": [ { @@ -1194,20 +1937,20 @@ "type": "github" } ], - "time": "2024-04-04T06:31:26+00:00" + "time": "2025-01-16T08:30:07+00:00" }, { "name": "sebastian/global-state", - "version": "dev-main", + "version": "7.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "8e38c9f37278523a7484c1f11830a4e323d3b179" + "reference": "5a559a8b70050ae2b8ee4a431232c8115ea91b2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/8e38c9f37278523a7484c1f11830a4e323d3b179", - "reference": "8e38c9f37278523a7484c1f11830a4e323d3b179", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/5a559a8b70050ae2b8ee4a431232c8115ea91b2b", + "reference": "5a559a8b70050ae2b8ee4a431232c8115ea91b2b", "shasum": "" }, "require": { @@ -1217,9 +1960,8 @@ }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1249,7 +1991,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/main" + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0" }, "funding": [ { @@ -1257,20 +1999,20 @@ "type": "github" } ], - "time": "2024-03-22T13:46:11+00:00" + "time": "2025-01-16T09:14:35+00:00" }, { "name": "sebastian/lines-of-code", - "version": "dev-main", + "version": "3.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "b60275143e48815ee6a3673f0227676774bca056" + "reference": "7ec7f9171e26ecb441dbdb0224ff994a133b60c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/b60275143e48815ee6a3673f0227676774bca056", - "reference": "b60275143e48815ee6a3673f0227676774bca056", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/7ec7f9171e26ecb441dbdb0224ff994a133b60c7", + "reference": "7ec7f9171e26ecb441dbdb0224ff994a133b60c7", "shasum": "" }, "require": { @@ -1278,9 +2020,8 @@ "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1308,7 +2049,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/main" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0" }, "funding": [ { @@ -1316,20 +2057,20 @@ "type": "github" } ], - "time": "2024-03-22T13:46:58+00:00" + "time": "2025-01-16T08:35:07+00:00" }, { "name": "sebastian/object-enumerator", - "version": "dev-main", + "version": "6.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "ab4ee4ea2987e495c755b5ace9aaa913124e1df7" + "reference": "2b74f801fe98397762d67edf28c0c803b901ea6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ab4ee4ea2987e495c755b5ace9aaa913124e1df7", - "reference": "ab4ee4ea2987e495c755b5ace9aaa913124e1df7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/2b74f801fe98397762d67edf28c0c803b901ea6a", + "reference": "2b74f801fe98397762d67edf28c0c803b901ea6a", "shasum": "" }, "require": { @@ -1338,9 +2079,8 @@ "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1367,7 +2107,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/main" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0" }, "funding": [ { @@ -1375,29 +2115,28 @@ "type": "github" } ], - "time": "2024-03-22T13:47:32+00:00" + "time": "2025-01-16T08:37:16+00:00" }, { "name": "sebastian/object-reflector", - "version": "dev-main", + "version": "4.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "ab3861c3fc853c753d9822e139e0d8be4fe364e5" + "reference": "7b3bcff19539050ca8ea314b185755f82fba7d92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/ab3861c3fc853c753d9822e139e0d8be4fe364e5", - "reference": "ab3861c3fc853c753d9822e139e0d8be4fe364e5", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/7b3bcff19539050ca8ea314b185755f82fba7d92", + "reference": "7b3bcff19539050ca8ea314b185755f82fba7d92", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1424,7 +2163,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/main" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0" }, "funding": [ { @@ -1432,29 +2171,28 @@ "type": "github" } ], - "time": "2024-03-22T13:48:42+00:00" + "time": "2025-01-16T08:39:28+00:00" }, { "name": "sebastian/recursion-context", - "version": "dev-main", + "version": "6.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "396fdbbdb95420649b3d0c4766b992da686c22fc" + "reference": "535fb763bca97d0f5beb4cc327f4b76a7c281010" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/396fdbbdb95420649b3d0c4766b992da686c22fc", - "reference": "396fdbbdb95420649b3d0c4766b992da686c22fc", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/535fb763bca97d0f5beb4cc327f4b76a7c281010", + "reference": "535fb763bca97d0f5beb4cc327f4b76a7c281010", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1489,7 +2227,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/main" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0" }, "funding": [ { @@ -1497,33 +2235,32 @@ "type": "github" } ], - "time": "2024-03-29T09:41:38+00:00" + "time": "2025-01-16T08:41:27+00:00" }, { "name": "sebastian/type", - "version": "dev-main", + "version": "5.1.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fa5a3eb73ada9ec9c2014399287147e1b4a18db7" + "reference": "89b125dbf292f30de4698e7f38efabaa85c56dbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fa5a3eb73ada9ec9c2014399287147e1b4a18db7", - "reference": "fa5a3eb73ada9ec9c2014399287147e1b4a18db7", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/89b125dbf292f30de4698e7f38efabaa85c56dbf", + "reference": "89b125dbf292f30de4698e7f38efabaa85c56dbf", "shasum": "" }, "require": { "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^11.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1547,7 +2284,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/type/issues", "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/main" + "source": "https://github.com/sebastianbergmann/type/tree/5.1" }, "funding": [ { @@ -1555,26 +2292,25 @@ "type": "github" } ], - "time": "2024-03-22T13:53:47+00:00" + "time": "2025-01-16T08:43:37+00:00" }, { "name": "sebastian/version", - "version": "dev-main", + "version": "5.0.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "975de64e70a76a46e743bac6e3210c6953068323" + "reference": "39b2cc232db6ec9bcfcdc94b73b0579151503d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/975de64e70a76a46e743bac6e3210c6953068323", - "reference": "975de64e70a76a46e743bac6e3210c6953068323", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/39b2cc232db6ec9bcfcdc94b73b0579151503d18", + "reference": "39b2cc232db6ec9bcfcdc94b73b0579151503d18", "shasum": "" }, "require": { "php": ">=8.2" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -1602,7 +2338,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/version/issues", "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/main" + "source": "https://github.com/sebastianbergmann/version/tree/5.0" }, "funding": [ { @@ -1610,7 +2346,209 @@ "type": "github" } ], - "time": "2024-03-22T13:54:56+00:00" + "time": "2025-01-16T08:45:51+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "default-branch": true, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/main" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-25T14:21:43+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/1.x" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-12-23T08:48:59+00:00" }, { "name": "theseer/tokenizer", @@ -1778,7 +2716,7 @@ "packages-dev": [], "aliases": [], "minimum-stability": "dev", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -1786,6 +2724,6 @@ "ext-mysqli": "*", "ext-curl": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/composer.phar b/composer.phar index 53f8b81265150bcfe95e433a7310d2e8652e88dc..4fa5122674b5547ffb636d45baf8677227f4eef6 100644 GIT binary patch delta 100238 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�#KLzVe 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 S-n!-64gd5{|70F>jQuYwthDg} diff --git a/contact.php b/contact.php index ea161dd..42f0cfc 100644 --- a/contact.php +++ b/contact.php @@ -1,69 +1,128 @@ send_message("Name: $name\nEmail: $email\nMessage: $message"); + $result = $telegram->send_message("Name: $name\nEmail: $email\nIP Address: $ipAddress\nMessage: $message"); } $title = $locale['contactus']; require_once 'includes/header.php'; -if ($_POST) { - if ($result['ok']) { - echo ''; - } else { - echo ''; - } -} ?> -
-
-
-
- -
+ + + + +
+ -
-
-
-
-

-

For any inquiries, please complete the form below.

-
+
+ + + +
+
+ +
+
+ + +
+ +
+
+

+

We'd love to hear from you. Send us a message and we'll respond as soon as possible.

-
-
-
-
+
+ +
+ +
+
+

Send us a Message

+ +
- +
-
+
- +
-
+
- +
- +
- + + diff --git a/dj.php b/dj.php index d1b1854..2969b61 100644 --- a/dj.php +++ b/dj.php @@ -151,7 +151,7 @@ require_once 'includes/header.php'; foreach ($mixes as $mix) { $output = new Mix($mix['slug'], $db); - $genres = $output->get_genres(); + $genres = $output->getGenres(); $genrelist = []; foreach ($genres as $genre) { @@ -164,8 +164,8 @@ require_once 'includes/header.php'; // Column for mix name and link echo ''; // End column @@ -185,7 +185,7 @@ require_once 'includes/header.php'; // Column for duration echo '
'; echo '

'; - $duration = $output->get_duration(); + $duration = $output->getDuration(); echo $duration['t']; echo '

'; echo '
'; // End column @@ -194,9 +194,9 @@ require_once 'includes/header.php'; echo '
'; echo '

'; // date format should just be year - $date = $output->get_recorded(); + $date = $output->getRecorded(); if (is_null($date) || empty(trim($date))) { - $date = $output->get_created(); + $date = $output->getCreated(); } echo date('Y', strtotime($date)); diff --git a/includes/footer.php b/includes/footer.php index 42e2cb1..324c93d 100644 --- a/includes/footer.php +++ b/includes/footer.php @@ -1,20 +1,33 @@ -

+
+ - \ No newline at end of file + diff --git a/includes/globals.php b/includes/globals.php index bb88f91..305e08f 100644 --- a/includes/globals.php +++ b/includes/globals.php @@ -4,24 +4,21 @@ require_once 'vendor/autoload.php'; use Yosymfony\Toml\Toml; +use DJMixHosting\SessionManager; $config = Toml::ParseFile('includes/config.toml'); require_once 'functions/i18n.php'; -require_once 'includes/sessions.php'; +// Instead of including sessions.php, start the session via SessionManager: +SessionManager::start(); + require_once 'includes/lang_loader.php'; - $mixshowsPages = ["/mixshows", "/mixshows/", "/mixshows.php"]; - $djsPages = ["/djs", "/djs/", "/djs.php"]; - $genrePages = ["/genres", "/genres/", "/genres.php"]; - $mixPages = ["/mix", "/mix/", "/mix.php"]; - $specialStyle = array_merge($mixshowsPages, $djsPages, $genrePages); - /** * @param int $count * @param mixed $dj @@ -51,7 +48,6 @@ function social_line($social, $value): string $icon = ""; $url = ""; $color = "#000000"; - switch ($social) { case "facebook": $icon = "fa-brands fa-facebook"; @@ -107,26 +103,22 @@ function social_line($social, $value): string $name = "Website"; break; } - return " -
  • - -

    $value -

    -
  • "; +
  • + +

    $value

    +
  • "; } function box_line($title, $value): string { - return "
    -
    -
    -

    $title

    -
    -
    -

    $value

    -
    -
    "; - -} \ No newline at end of file +
    +
    +

    $title

    +
    +
    +

    $value

    +
    +
    "; +} diff --git a/includes/header-meta.php b/includes/header-meta.php index 9e16884..7654117 100644 --- a/includes/header-meta.php +++ b/includes/header-meta.php @@ -18,4 +18,3 @@ if (isset($mix)) { echo $meta; } } - diff --git a/includes/header.php b/includes/header.php index dcdf6a0..100ffb0 100644 --- a/includes/header.php +++ b/includes/header.php @@ -1,11 +1,14 @@ - - + + + - diff --git a/includes/sessions.php b/includes/sessions.php deleted file mode 100644 index 843a24e..0000000 --- a/includes/sessions.php +++ /dev/null @@ -1,8 +0,0 @@ - "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/ar-SA/messages.php b/locale/ar-SA/messages.php index 97e6de5..ea2aba4 100644 --- a/locale/ar-SA/messages.php +++ b/locale/ar-SA/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'مرحبا بكم في موقعنا على الإنترنت!', 'description' => 'هذا وصف بالإنكليزية.', - 'desc' => 'Description', + 'desc' => 'الوصف', 'userProfile' => "الملف الشخصي للمستخدم", 'user' => 'المستخدم', 'home' => 'المنزل', @@ -14,17 +14,17 @@ return [ 'login' => 'تسجيل الدخول', 'message' => 'رسالة', 'follow' => 'اتبع', - 'djs' => 'DJs', + 'djs' => 'دي جي', "djNotFound" => "تعذر تحميل DJ; إما لم يتم العثور على DJ أو هذا DJ خاص.", "notfound" => "لم يتم العثور على الصفحة", "genre" => "النوع", - "genres" => "Genres", + "genres" => "أنواع الموسيقى", "genreNotFound" => "لا يمكن تحميل النوع الجيد؛ إما لم يتم العثور على هذا النوع، أو كان فارغا، أو هذا النوع خاص.", "mix-count" => "عدد المزيج", "mixes" => "خلط", "mix" => "خليط", "mixNotFound" => "تعذر تحميل المزيج ؛ إما لم يتم العثور على المزيج ، أو كان فارغا، أو هذا المزيج خاص.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "تعذر تحميل الخليط؛ إما لم يتم العثور على الخليط، أو كان فارغاً، أو هذا الخليط خاص.", "mixName" => "اسم المزيج", "mixDescription" => "وصف المزيج", "mixLength" => "مزيج الطول", @@ -54,18 +54,23 @@ return [ "plays" => "مشغلات", "play" => "تشغيل", "contactus" => "اتصل بنا", - "allrightsreserved" => "جميع الحقوق محفوظة.format@@0", - "mixshows" => "Mixshows", - "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "allrightsreserved" => "جميع الحقوق محفوظة.", + "mixshows" => "المزج", + "mixshow" => "عرض ميكس", + "mixshowName" => "اسم المزج", + "share" => "مشاركة", + "sahrethismix" => "شارك هذا المزيج", + "sharethismixshow" => "شارك هذا المزيج", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "السنة", + "sharetotwitter" => "شارك إلى X (تويتر سابقاً)", + "sharetofb" => "مشاركة على Facebook", + "sharetoig" => "مشاركة على Instagram", + "copyurl" => "نسخ الرابط", + "urlcopiedtoclipboard" => "تم نسخ عنوان URL إلى الحافظة", + "failedtocopyurl" => "فشل في نسخ الرابط", + "name" => "الاسم", + "username" => "اسم المستخدم", + "logout" => "تسجيل الخروج", + "upload" => "تحميل", ]; \ No newline at end of file diff --git a/locale/ca-ES/messages.php b/locale/ca-ES/messages.php index afd1a35..8f5993b 100644 --- a/locale/ca-ES/messages.php +++ b/locale/ca-ES/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/cs-CZ/messages.php b/locale/cs-CZ/messages.php index 16a70ba..8c91f7d 100644 --- a/locale/cs-CZ/messages.php +++ b/locale/cs-CZ/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Vítejte na našich webových stránkách!', 'description' => 'To je popis v angličtině.', - 'desc' => 'Description', + 'desc' => 'L 343, 22.12.2009, s. 1).', 'userProfile' => "Profil uživatele", 'user' => 'Uživatel', 'home' => 'Domů', @@ -24,7 +24,7 @@ return [ "mixes" => "Směsi", "mix" => "Míchat", "mixNotFound" => "Nelze načíst mix; buď směs nebyla nalezena, byla prázdná, nebo je tato směs soukromá.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Nelze načíst mixshow; buď mixshow nebyl nalezen, byl prázdný, nebo je tento mixshow soukromý.", "mixName" => "Směsný název", "mixDescription" => "Smíchat popis", "mixLength" => "Míchat délku", @@ -55,17 +55,22 @@ return [ "play" => "Hrát", "contactus" => "Kontaktujte nás", "allrightsreserved" => "Všechna práva vyhrazena.", - "mixshows" => "Mixshows", + "mixshows" => "Směšovače", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Název Mixshow", + "share" => "Sdílet", + "sahrethismix" => "Sdílet tuto skladbu", + "sharethismixshow" => "Sdílet tento mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Rok", + "sharetotwitter" => "Sdílet na X (dříve Twitter)", + "sharetofb" => "Sdílet na Facebook", + "sharetoig" => "Sdílet na Instagramu", + "copyurl" => "Kopírovat URL", + "urlcopiedtoclipboard" => "URL zkopírováno do schránky", + "failedtocopyurl" => "Kopírování URL se nezdařilo", + "name" => "Název", + "username" => "Uživatelské jméno", + "logout" => "Odhlásit se", + "upload" => "Nahrát", ]; \ No newline at end of file diff --git a/locale/da-DK/messages.php b/locale/da-DK/messages.php index 2812713..3676dc8 100644 --- a/locale/da-DK/messages.php +++ b/locale/da-DK/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Velkommen til vores hjemmeside!', 'description' => 'Dette er en beskrivelse på engelsk.', - 'desc' => 'Description', + 'desc' => 'Varebeskrivelse', 'userProfile' => "Bruger Profil", 'user' => 'Bruger', 'home' => 'Hjem', @@ -24,7 +24,7 @@ return [ "mixes" => "Blandinger", "mix" => "Bland", "mixNotFound" => "Kunne ikke indlæse mix. Enten blev blandingen ikke fundet, var tom, eller også er dette miks privat.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Kunne ikke indlæse mixshow; enten blev mixshowet ikke fundet, var tomt, eller dette mixshow er privat.", "mixName" => "Mix Navn", "mixDescription" => "Bland Beskrivelse", "mixLength" => "Bland Længde", @@ -57,15 +57,20 @@ return [ "allrightsreserved" => "Alle rettigheder forbeholdt.", "mixshows" => "Mixshows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mixshow Navn", + "share" => "Del", + "sahrethismix" => "Del dette mix", + "sharethismixshow" => "Del dette mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "År", + "sharetotwitter" => "Del til X (tidligere Twitter)", + "sharetofb" => "Del på Facebook", + "sharetoig" => "Del på Instagram", + "copyurl" => "Kopiér URL", + "urlcopiedtoclipboard" => "URL kopieret til udklipsholder", + "failedtocopyurl" => "Kopiering af URL mislykkedes", + "name" => "Navn", + "username" => "Brugernavn", + "logout" => "Log Ud", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/de-DE/messages.php b/locale/de-DE/messages.php index be2a138..a7bb1e6 100644 --- a/locale/de-DE/messages.php +++ b/locale/de-DE/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Willkommen auf unserer Website!', 'description' => 'Dies ist eine Beschreibung auf Englisch.', - 'desc' => 'Description', + 'desc' => 'Beschreibung', 'userProfile' => "Benutzerprofil", 'user' => 'Benutzer', 'home' => 'Zuhause', @@ -24,7 +24,7 @@ return [ "mixes" => "Mischungen", "mix" => "Mix", "mixNotFound" => "Mix konnte nicht geladen werden; entweder wurde der Mix nicht gefunden, war leer oder dieser Mix ist privat.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Mixshow konnte nicht geladen werden; entweder wurde die Mixshow nicht gefunden, war leer oder diese Mixshow ist privat.", "mixName" => "Mix-Name", "mixDescription" => "Mix-Beschreibung", "mixLength" => "Mix-Länge", @@ -55,17 +55,22 @@ return [ "play" => "Abspielen", "contactus" => "Kontaktiere uns", "allrightsreserved" => "Alle Rechte vorbehalten.", - "mixshows" => "Mixshows", + "mixshows" => "Mix-Shows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mix-Show-Name", + "share" => "Teilen", + "sahrethismix" => "Diesen Mix teilen", + "sharethismixshow" => "Diese Mixshow teilen", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Jahr", + "sharetotwitter" => "Auf X teilen (ehemals Twitter)", + "sharetofb" => "Auf Facebook teilen", + "sharetoig" => "Auf Instagram teilen", + "copyurl" => "URL kopieren", + "urlcopiedtoclipboard" => "URL in Zwischenablage kopiert", + "failedtocopyurl" => "Fehler beim Kopieren der URL", + "name" => "Name", + "username" => "Benutzername", + "logout" => "Abmelden", + "upload" => "Hochladen", ]; \ No newline at end of file diff --git a/locale/el-GR/messages.php b/locale/el-GR/messages.php index 5a810ee..25231de 100644 --- a/locale/el-GR/messages.php +++ b/locale/el-GR/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Καλώς ήλθατε στην ιστοσελίδα μας!', 'description' => 'Αυτή είναι μια περιγραφή στα αγγλικά.', - 'desc' => 'Description', + 'desc' => 'Περιγραφή', 'userProfile' => "Προφίλ Χρήστη", 'user' => 'Χρήστης', 'home' => 'Αρχική', @@ -24,7 +24,7 @@ return [ "mixes" => "Μείγματα", "mix" => "Μείγμα", "mixNotFound" => "Δεν ήταν δυνατή η φόρτωση του μείγματος. Είτε το μείγμα δεν βρέθηκε, ήταν άδειο, είτε αυτό το μίγμα είναι ιδιωτικό.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Δεν ήταν δυνατή η φόρτωση του mixshow. Είτε το mixshow δεν βρέθηκε, ήταν άδειο, είτε αυτό το mixshow είναι ιδιωτικό.", "mixName" => "Όνομα Μεικτού", "mixDescription" => "Περιγραφή Μεικτού", "mixLength" => "Μήκος Μείγματος", @@ -55,17 +55,22 @@ return [ "play" => "Αναπαραγωγή", "contactus" => "Επικοινωνήστε Μαζί Μας", "allrightsreserved" => "Με επιφύλαξη παντός δικαιώματος.", - "mixshows" => "Mixshows", + "mixshows" => "Μείγματα", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Όνομα Mixshow", + "share" => "Κοινοποίηση", + "sahrethismix" => "Μοιραστείτε αυτό το μίγμα", + "sharethismixshow" => "Μοιραστείτε αυτό το μίγμα", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Έτος", + "sharetotwitter" => "Μοιραστείτε στο X (πρώην Twitter)", + "sharetofb" => "Κοινοποίηση στο Facebook", + "sharetoig" => "Κοινοποίηση στο Instagram", + "copyurl" => "Αντιγραφή URL", + "urlcopiedtoclipboard" => "Το URL αντιγράφηκε στο πρόχειρο", + "failedtocopyurl" => "Αποτυχία αντιγραφής URL", + "name" => "Όνομα", + "username" => "Όνομα Χρήστη", + "logout" => "Αποσύνδεση", + "upload" => "Ανέβασμα", ]; \ No newline at end of file diff --git a/locale/en-US/messages.php b/locale/en-US/messages.php index 2804409..9f3209e 100644 --- a/locale/en-US/messages.php +++ b/locale/en-US/messages.php @@ -71,4 +71,17 @@ return [ "failedtocopyurl" => "Failed to copy URL", "name" => "Name", "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", + "loginToVerifyEmail" => "You must be logged in to verify your email.", + "loginToUploadMix" => "You must be logged in to upload a mix.", + "verificationCodeRequired" => "Verification code is required.", + "recordedDate" => "Recorded Date", + "noUploadedFileFound" => "No uploaded file found. Please upload a mix file.", + "mixTitleRequired" => "Mix title is required.", + "errorUploadCDN" => "Error uploading file to CDN: ", + "errorSavingMixDB" => "Error saving mix to database.", + "uploadedPendingApproval" => "Mix uploaded successfully and is pending approval.", + "uploadHeader1" => "Upload your mix to Utah's DJs" + ]; \ No newline at end of file diff --git a/locale/es-ES/messages.php b/locale/es-ES/messages.php index 2d7fece..338c9fb 100644 --- a/locale/es-ES/messages.php +++ b/locale/es-ES/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => '¡Bienvenido a nuestro sitio web!', 'description' => 'This is a description in Spanish.', - 'desc' => 'Description', + 'desc' => 'Descripción', 'userProfile' => "Perfil de usuario", 'user' => 'Usuario', 'home' => 'Inicio', @@ -24,7 +24,7 @@ return [ "mixes" => "Mezclas", "mix" => "Mezcla", "mixNotFound" => "No se pudo cargar la mezcla; o bien la mezcla no fue encontrada, estaba vacía, o esta mezcla es privada.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "No se pudo cargar mixshow; o bien el mixshow no fue encontrado, estaba vacío, o este mixshow es privado.", "mixName" => "Mezclar nombre", "mixDescription" => "Mezclar descripción", "mixLength" => "Mezclar longitud", @@ -57,15 +57,20 @@ return [ "allrightsreserved" => "Todos los derechos reservados.", "mixshows" => "Mixshows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Nombre de Mixshow", + "share" => "Compartir", + "sahrethismix" => "Compartir esta mezcla", + "sharethismixshow" => "Compartir este mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Año", + "sharetotwitter" => "Compartir en X (anteriormente Twitter)", + "sharetofb" => "Compartir en Facebook", + "sharetoig" => "Compartir en Instagram", + "copyurl" => "Copiar URL", + "urlcopiedtoclipboard" => "URL copiada al portapapeles", + "failedtocopyurl" => "Error al copiar la URL", + "name" => "Nombre", + "username" => "Usuario", + "logout" => "Cerrar sesión", + "upload" => "Subir", ]; \ No newline at end of file diff --git a/locale/fi-FI/messages.php b/locale/fi-FI/messages.php index c77402a..0c4b838 100644 --- a/locale/fi-FI/messages.php +++ b/locale/fi-FI/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Tervetuloa sivustollemme!', 'description' => 'Tämä on englanninkielinen kuvaus.', - 'desc' => 'Description', + 'desc' => 'Kuvaus', 'userProfile' => "Käyttäjän Profiili", 'user' => 'Käyttäjä', 'home' => 'Koti', @@ -24,7 +24,7 @@ return [ "mixes" => "Sekoitukset", "mix" => "Sekoita", "mixNotFound" => "Sekoitusta ei voitu ladata. Sekoitus ei löytynyt, se oli tyhjä, tai tämä sekoitus on yksityinen.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Sekoitusnäyttöä ei voitu ladata. Sekoitusnäyttöä ei löytynyt, se oli tyhjä, tai tämä mixshow on yksityinen.", "mixName" => "Sekoita Nimi", "mixDescription" => "Sekoita Kuvaus", "mixLength" => "Sekoita Pituus", @@ -57,15 +57,20 @@ return [ "allrightsreserved" => "Kaikki oikeudet pidätetään.", "mixshows" => "Mixshows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mixshow Nimi", + "share" => "Jaa", + "sahrethismix" => "Jaa tämä sekoitus", + "sharethismixshow" => "Jaa tämä mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Vuosi", + "sharetotwitter" => "Jaa kohtaan X (entinen Twitter)", + "sharetofb" => "Jaa Facebookiin", + "sharetoig" => "Jaa Instagramiin", + "copyurl" => "Kopioi URL", + "urlcopiedtoclipboard" => "URL kopioitu leikepöydälle", + "failedtocopyurl" => "URL-osoitteen kopiointi epäonnistui", + "name" => "Nimi", + "username" => "Käyttäjätunnus", + "logout" => "Kirjaudu Ulos", + "upload" => "Lähetä", ]; \ No newline at end of file diff --git a/locale/fil-PH/messages.php b/locale/fil-PH/messages.php index 1454cd5..8f1dca7 100644 --- a/locale/fil-PH/messages.php +++ b/locale/fil-PH/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/fr-FR/messages.php b/locale/fr-FR/messages.php index 97d8903..b399a35 100644 --- a/locale/fr-FR/messages.php +++ b/locale/fr-FR/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Bienvenue sur notre site Web!', 'description' => 'Ceci est une description en français.', - 'desc' => 'Description', + 'desc' => 'Libellé', 'userProfile' => "Profil de l'utilisateur", 'user' => 'Utilisateur', 'home' => 'Domicile', @@ -24,7 +24,7 @@ return [ "mixes" => "Mixes", "mix" => "Mélanger", "mixNotFound" => "Impossible de charger le mixage; soit le mixage n'a pas été trouvé, soit le mixage est vide, soit ce mixage est privé.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Impossible de charger le mixshow ; soit le mixshow n'a pas été trouvé, soit le mixshow est vide, soit ce mixshow est privé.", "mixName" => "Nom du mixage", "mixDescription" => "Description du mixage", "mixLength" => "Longueur du mixage", @@ -57,15 +57,20 @@ return [ "allrightsreserved" => "Tous droits réservés.", "mixshows" => "Mixshows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", - "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "mixshowName" => "Nom du Mixshow", + "share" => "Partager", + "sahrethismix" => "Partager ce mix", + "sharethismixshow" => "Partager ce mixshow", + "rss" => "Flux RSS", + "year" => "Année", + "sharetotwitter" => "Partager vers X (anciennement Twitter)", + "sharetofb" => "Partager sur Facebook", + "sharetoig" => "Partager sur Instagram", + "copyurl" => "Copier l'URL", + "urlcopiedtoclipboard" => "URL copiée dans le presse-papiers", + "failedtocopyurl" => "Échec de la copie de l'URL", + "name" => "Nom", + "username" => "Nom d'utilisateur", + "logout" => "Déconnexion", + "upload" => "Charger", ]; \ No newline at end of file diff --git a/locale/he-IL/messages.php b/locale/he-IL/messages.php index afd1a35..8f5993b 100644 --- a/locale/he-IL/messages.php +++ b/locale/he-IL/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/hu-HU/messages.php b/locale/hu-HU/messages.php index afd1a35..8f5993b 100644 --- a/locale/hu-HU/messages.php +++ b/locale/hu-HU/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/it-IT/messages.php b/locale/it-IT/messages.php index c11c992..a6e131c 100644 --- a/locale/it-IT/messages.php +++ b/locale/it-IT/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Benvenuto nel nostro sito Web!', 'description' => 'Questa è una descrizione in inglese.', - 'desc' => 'Description', + 'desc' => 'Descrizione', 'userProfile' => "Profilo Utente", 'user' => 'Utente', 'home' => 'Home', @@ -24,7 +24,7 @@ return [ "mixes" => "Miscele", "mix" => "Miscela", "mixNotFound" => "Impossibile caricare il mix; o il mix non è stato trovato, è vuoto, o questo mix è privato.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Impossibile caricare mixshow; o il mixshow non è stato trovato, è stato vuoto, o questo mixshow è privato.", "mixName" => "Nome Mix", "mixDescription" => "Descrizione Mix", "mixLength" => "Miscela Lunghezza", @@ -55,17 +55,22 @@ return [ "play" => "Gioca", "contactus" => "Contattaci", "allrightsreserved" => "Tutti i diritti riservati.", - "mixshows" => "Mixshows", + "mixshows" => "Mixshow", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Nome Mixshow", + "share" => "Condividi", + "sahrethismix" => "Condividi questo mix", + "sharethismixshow" => "Condividi questo mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Anno", + "sharetotwitter" => "Condividi su X (ex Twitter)", + "sharetofb" => "Condividi su Facebook", + "sharetoig" => "Condividi su Instagram", + "copyurl" => "Copia URL", + "urlcopiedtoclipboard" => "URL copiato negli appunti", + "failedtocopyurl" => "Impossibile copiare l'URL", + "name" => "Nome", + "username" => "Username", + "logout" => "Esci", + "upload" => "Carica", ]; \ No newline at end of file diff --git a/locale/ja-JP/messages.php b/locale/ja-JP/messages.php index e46ddc9..557ea71 100644 --- a/locale/ja-JP/messages.php +++ b/locale/ja-JP/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => '私たちのウェブサイトへようこそ!', 'description' => 'これは英語の説明です。', - 'desc' => 'Description', + 'desc' => '説明', 'userProfile' => "ユーザープロフィール", 'user' => 'ユーザー', 'home' => 'ホーム', @@ -24,7 +24,7 @@ return [ "mixes" => "ミックス", "mix" => "ミックス", "mixNotFound" => "ミックスをロードできませんでした。ミックスが見つかりませんでした。空であるか、このミックスがプライベートです。", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "mixshowをロードできませんでした。mixshowが見つかりませんでした。空か、このmixshowはプライベートです。", "mixName" => "ミックス名", "mixDescription" => "ミックスの説明", "mixLength" => "ミックス長さ", @@ -55,17 +55,22 @@ return [ "play" => "再生", "contactus" => "お問い合わせ", "allrightsreserved" => "All rights reserved.", - "mixshows" => "Mixshows", + "mixshows" => "ミックスショー", "mixshow" => "Mixshow", "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "share" => "共有", + "sahrethismix" => "このミックスを共有", + "sharethismixshow" => "このミックスショーを共有", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "年", + "sharetotwitter" => "X(旧 Twitter)で共有", + "sharetofb" => "Facebookで共有", + "sharetoig" => "Instagramで共有", + "copyurl" => "URLをコピー", + "urlcopiedtoclipboard" => "URL をクリップボードにコピーしました", + "failedtocopyurl" => "URLのコピーに失敗しました", + "name" => "名前", + "username" => "ユーザー名", + "logout" => "ログアウト", + "upload" => "アップロード", ]; \ No newline at end of file diff --git a/locale/ko-KR/messages.php b/locale/ko-KR/messages.php index afd1a35..8f5993b 100644 --- a/locale/ko-KR/messages.php +++ b/locale/ko-KR/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/nl-NL/messages.php b/locale/nl-NL/messages.php index a597340..0f8beaf 100644 --- a/locale/nl-NL/messages.php +++ b/locale/nl-NL/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Welkom op onze Website!', 'description' => 'Dit is een beschrijving in het Engels.', - 'desc' => 'Description', + 'desc' => 'Beschrijving', 'userProfile' => "Gebruikers Profiel", 'user' => 'Gebruiker', 'home' => 'Startpagina', @@ -24,7 +24,7 @@ return [ "mixes" => "Mixen", "mix" => "Mengen", "mixNotFound" => "Kon mixen niet laden; of de mix is niet gevonden, was leeg, of deze mix is privé.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Kon mixshow niet laden; of de mixshow is niet gevonden, was leeg, of deze mixshow is privé.", "mixName" => "Mix Naam", "mixDescription" => "Beschrijving mixen", "mixLength" => "Mix Lengte", @@ -55,17 +55,22 @@ return [ "play" => "Afspelen", "contactus" => "Contacteer ons", "allrightsreserved" => "Alle rechten voorbehouden.format@@0", - "mixshows" => "Mixshows", + "mixshows" => "Mixseries", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mixshow Naam", + "share" => "Delen", + "sahrethismix" => "Deel deze mix", + "sharethismixshow" => "Deel deze mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "jaar", + "sharetotwitter" => "Deel met X (voorheen Twitter)", + "sharetofb" => "Delen op Facebook", + "sharetoig" => "Delen op Instagram", + "copyurl" => "URL kopiëren", + "urlcopiedtoclipboard" => "URL gekopieerd naar klembord", + "failedtocopyurl" => "Kopiëren van URL mislukt", + "name" => "naam", + "username" => "Gebruikersnaam", + "logout" => "Afmelden", + "upload" => "Uploaden", ]; \ No newline at end of file diff --git a/locale/no-NO/messages.php b/locale/no-NO/messages.php index a10aa1f..924c895 100644 --- a/locale/no-NO/messages.php +++ b/locale/no-NO/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Velkommen til vår hjemmeside!', 'description' => 'Dette er en beskrivelse på engelsk.', - 'desc' => 'Description', + 'desc' => 'Beskrivelse', 'userProfile' => "Bruker profil", 'user' => 'Bruker', 'home' => 'Hjem', @@ -24,7 +24,7 @@ return [ "mixes" => "Mixes", "mix" => "Bland", "mixNotFound" => "Kunne ikke laste blanding, verken var blandingen tom, eller så var denne blandingen privat.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Kan ikke laste mixshow; verken ble ikke funnet, var tom, eller denne blandingen er privat.", "mixName" => "Blandet navn", "mixDescription" => "Bland beskrivelse", "mixLength" => "Blandet lengde", @@ -57,15 +57,20 @@ return [ "allrightsreserved" => "Med enerett.", "mixshows" => "Mixshows", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mixshow navn", + "share" => "Del", + "sahrethismix" => "Del denne blandingen", + "sharethismixshow" => "Del denne blandingen", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "År", + "sharetotwitter" => "Del til X (tidligere Twitter)", + "sharetofb" => "Del på Facebook", + "sharetoig" => "Del på Instagram", + "copyurl" => "Kopier URL", + "urlcopiedtoclipboard" => "URL kopiert til utklippstavlen", + "failedtocopyurl" => "Klarte ikke å kopiere URL", + "name" => "Navn", + "username" => "Brukernavn", + "logout" => "Logg", + "upload" => "Last opp", ]; \ No newline at end of file diff --git a/locale/pl-PL/messages.php b/locale/pl-PL/messages.php index d7d7bec..a972519 100644 --- a/locale/pl-PL/messages.php +++ b/locale/pl-PL/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Witamy na naszej stronie internetowej!', 'description' => 'To jest opis w języku angielskim.', - 'desc' => 'Description', + 'desc' => 'Opis', 'userProfile' => "Profil użytkownika", 'user' => 'Użytkownik', 'home' => 'Strona główna', @@ -24,7 +24,7 @@ return [ "mixes" => "Mixy", "mix" => "Mieszanina", "mixNotFound" => "Nie można załadować miksy; albo mieszanina nie została znaleziona, była pusta lub ta miksy jest prywatna.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Nie można załadować mixshow; albo mixshow nie został znaleziony, był pusty, albo mixshow jest prywatny.", "mixName" => "Nazwa mixu", "mixDescription" => "Opis mieszaniny", "mixLength" => "Długość mieszania", @@ -55,17 +55,22 @@ return [ "play" => "Odtwórz", "contactus" => "Skontaktuj się z nami", "allrightsreserved" => "Wszystkie prawa zastrzeżone.", - "mixshows" => "Mixshows", + "mixshows" => "Mieszanki", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Nazwa Mixshow", + "share" => "Udostępnij", + "sahrethismix" => "Udostępnij ten koszyk", + "sharethismixshow" => "Udostępnij ten mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "W związku z tym Komisja stwierdza, że środek 1 stanowi pomoc państwa w rozumieniu art. 107 ust. 1 Traktatu.", + "sharetotwitter" => "Udostępnij do X (dawniej Twitter)", + "sharetofb" => "Udostępnij na Facebooku", + "sharetoig" => "Udostępnij na Instagramie", + "copyurl" => "Kopiuj adres URL", + "urlcopiedtoclipboard" => "Adres URL skopiowany do schowka", + "failedtocopyurl" => "Nie udało się skopiować adresu URL", + "name" => "Nazwisko", + "username" => "Nazwa użytkownika", + "logout" => "Wyloguj się", + "upload" => "Prześlij", ]; \ No newline at end of file diff --git a/locale/pt-BR/messages.php b/locale/pt-BR/messages.php index eee6746..aa7b943 100644 --- a/locale/pt-BR/messages.php +++ b/locale/pt-BR/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Bem-vindo ao nosso site!', 'description' => 'Esta é uma descrição em inglês.', - 'desc' => 'Description', + 'desc' => 'Descrição:', 'userProfile' => "Informações do Perfil", 'user' => 'Usuário', 'home' => 'Residencial', @@ -24,7 +24,7 @@ return [ "mixes" => "Misturar", "mix" => "Mistura", "mixNotFound" => "Não foi possível carregar o mix; ou a mistura não foi encontrada, estava vazia, ou esta mistura é privada.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Não foi possível carregar o mixshow; ou o mixshow não foi encontrado, estava vazio ou este mixshow é privado.", "mixName" => "Nome do mix", "mixDescription" => "Descrição Misto", "mixLength" => "Comprimento Misturado", @@ -55,17 +55,22 @@ return [ "play" => "Reproduzir", "contactus" => "Entre em contato", "allrightsreserved" => "Todos os direitos reservados.", - "mixshows" => "Mixshows", + "mixshows" => "Misturas", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", - "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "mixshowName" => "Nome do Mixshow", + "share" => "Compartilhar", + "sahrethismix" => "Compartilhe esta mistura", + "sharethismixshow" => "Compartilhar este mixshow", + "rss" => "Resposta", + "year" => "ano", + "sharetotwitter" => "Compartilhar para X (antigo Twitter)", + "sharetofb" => "Compartilhar no Facebook", + "sharetoig" => "Compartilhar com o Instagram", + "copyurl" => "Copiar URL", + "urlcopiedtoclipboard" => "URL copiado para área de transferência", + "failedtocopyurl" => "Falha ao copiar URL", + "name" => "Nome:", + "username" => "Usuário:", + "logout" => "Desconectar", + "upload" => "Transferir", ]; \ No newline at end of file diff --git a/locale/pt-PT/messages.php b/locale/pt-PT/messages.php index eee6746..aa7b943 100644 --- a/locale/pt-PT/messages.php +++ b/locale/pt-PT/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Bem-vindo ao nosso site!', 'description' => 'Esta é uma descrição em inglês.', - 'desc' => 'Description', + 'desc' => 'Descrição:', 'userProfile' => "Informações do Perfil", 'user' => 'Usuário', 'home' => 'Residencial', @@ -24,7 +24,7 @@ return [ "mixes" => "Misturar", "mix" => "Mistura", "mixNotFound" => "Não foi possível carregar o mix; ou a mistura não foi encontrada, estava vazia, ou esta mistura é privada.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Não foi possível carregar o mixshow; ou o mixshow não foi encontrado, estava vazio ou este mixshow é privado.", "mixName" => "Nome do mix", "mixDescription" => "Descrição Misto", "mixLength" => "Comprimento Misturado", @@ -55,17 +55,22 @@ return [ "play" => "Reproduzir", "contactus" => "Entre em contato", "allrightsreserved" => "Todos os direitos reservados.", - "mixshows" => "Mixshows", + "mixshows" => "Misturas", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", - "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "mixshowName" => "Nome do Mixshow", + "share" => "Compartilhar", + "sahrethismix" => "Compartilhe esta mistura", + "sharethismixshow" => "Compartilhar este mixshow", + "rss" => "Resposta", + "year" => "ano", + "sharetotwitter" => "Compartilhar para X (antigo Twitter)", + "sharetofb" => "Compartilhar no Facebook", + "sharetoig" => "Compartilhar com o Instagram", + "copyurl" => "Copiar URL", + "urlcopiedtoclipboard" => "URL copiado para área de transferência", + "failedtocopyurl" => "Falha ao copiar URL", + "name" => "Nome:", + "username" => "Usuário:", + "logout" => "Desconectar", + "upload" => "Transferir", ]; \ No newline at end of file diff --git a/locale/ro-RO/messages.php b/locale/ro-RO/messages.php index 705c1b7..10c467f 100644 --- a/locale/ro-RO/messages.php +++ b/locale/ro-RO/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Bun venit pe site-ul nostru!', 'description' => 'Aceasta este o descriere în engleză.', - 'desc' => 'Description', + 'desc' => 'Descriere', 'userProfile' => "Profil utilizator", 'user' => 'Utilizator', 'home' => 'Acasă', @@ -24,7 +24,7 @@ return [ "mixes" => "Mixuri", "mix" => "Amestecă", "mixNotFound" => "Nu s-a putut încărca mixul; fie mixul nu a fost găsit, a fost gol, fie acest mix este privat.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Nu s-a putut încărca mixshow-ul; fie emisiunea mixtă nu a fost găsită, a fost goală, fie acest spectacol mixt este privat.", "mixName" => "Nume mix", "mixDescription" => "Descriere mixtă", "mixLength" => "Amestecă lungimea", @@ -55,17 +55,22 @@ return [ "play" => "Redare", "contactus" => "Contactează-ne", "allrightsreserved" => "Toate drepturile rezervate.", - "mixshows" => "Mixshows", + "mixshows" => "Amestec", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Nume Mixshow", + "share" => "Distribuie", + "sahrethismix" => "Distribuie acest mix", + "sharethismixshow" => "Distribuie acest spectacol mixt", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "An", + "sharetotwitter" => "Distribuie pe X (anterior Twitter)", + "sharetofb" => "Distribuie pe Facebook", + "sharetoig" => "Distribuie pe Instagram", + "copyurl" => "Copiază URL-ul", + "urlcopiedtoclipboard" => "URL copiat în clipboard", + "failedtocopyurl" => "Copierea adresei URL a eșuat", + "name" => "Nume", + "username" => "Nume", + "logout" => "Deconectare", + "upload" => "Incarca", ]; \ No newline at end of file diff --git a/locale/ru-RU/messages.php b/locale/ru-RU/messages.php index 66d98b3..43e7885 100644 --- a/locale/ru-RU/messages.php +++ b/locale/ru-RU/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Добро пожаловать на наш сайт!', 'description' => 'Это описание на английском языке.', - 'desc' => 'Description', + 'desc' => 'Описание', 'userProfile' => "Профиль пользователя", 'user' => 'Пользователь', 'home' => 'Домашний', @@ -24,7 +24,7 @@ return [ "mixes" => "Миксы", "mix" => "Микс", "mixNotFound" => "Не удалось загрузить смесь; либо смесь не найдена, либо эта смесь является приватной.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Не удалось загрузить mixshow; либо mixshow не найден, либо эта mixshow является приватной.", "mixName" => "Название микса", "mixDescription" => "Описание смеси", "mixLength" => "Длина микса", @@ -55,17 +55,22 @@ return [ "play" => "Играть", "contactus" => "Свяжитесь с нами", "allrightsreserved" => "Все права защищены.", - "mixshows" => "Mixshows", + "mixshows" => "Смешанные шоу", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", - "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "mixshowName" => "Название Mixshow", + "share" => "Поделиться", + "sahrethismix" => "Поделиться этой смесью", + "sharethismixshow" => "Поделиться этой смесительной шоу", + "rss" => "RSS-лента", + "year" => "Год", + "sharetotwitter" => "Поделиться с X (ранее Twitter)", + "sharetofb" => "Поделиться на Facebook", + "sharetoig" => "Поделиться в Instagram", + "copyurl" => "Копировать URL", + "urlcopiedtoclipboard" => "URL скопирован в буфер обмена", + "failedtocopyurl" => "Не удалось скопировать URL", + "name" => "Наименование", + "username" => "Имя пользователя", + "logout" => "Выйти", + "upload" => "Выгрузить", ]; \ No newline at end of file diff --git a/locale/sr-SP/messages.php b/locale/sr-SP/messages.php index afd1a35..8f5993b 100644 --- a/locale/sr-SP/messages.php +++ b/locale/sr-SP/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/sv-SE/messages.php b/locale/sv-SE/messages.php index 93ff57a..624c66c 100644 --- a/locale/sv-SE/messages.php +++ b/locale/sv-SE/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Välkommen till vår webbplats!', 'description' => 'Detta är en beskrivning på engelska.', - 'desc' => 'Description', + 'desc' => 'Beskrivning', 'userProfile' => "Användarprofil", 'user' => 'Användare', 'home' => 'Hem', @@ -24,7 +24,7 @@ return [ "mixes" => "Blandningar", "mix" => "Blanda", "mixNotFound" => "Kunde inte ladda mix; antingen hittades blandningen inte, var tom, eller denna blandning är privat.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Kunde inte ladda mixshow; antingen hittades inte mixshowen, var tom, eller så är denna mixshow privat.", "mixName" => "Blanda namn", "mixDescription" => "Blanda beskrivning", "mixLength" => "Blanda längd", @@ -55,17 +55,22 @@ return [ "play" => "Spela", "contactus" => "Kontakta oss", "allrightsreserved" => "Alla rättigheter reserverade.", - "mixshows" => "Mixshows", + "mixshows" => "Blandningsserier", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Mixseriens namn", + "share" => "Dela", + "sahrethismix" => "Dela denna mix", + "sharethismixshow" => "Dela denna mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "År", + "sharetotwitter" => "Dela till X (tidigare Twitter)", + "sharetofb" => "Dela på Facebook", + "sharetoig" => "Dela på Instagram", + "copyurl" => "Kopiera URL", + "urlcopiedtoclipboard" => "URL kopierad till urklipp", + "failedtocopyurl" => "Kunde inte kopiera URL", + "name" => "Namn", + "username" => "Användarnamn", + "logout" => "Utloggning", + "upload" => "Ladda upp", ]; \ No newline at end of file diff --git a/locale/tr-TR/messages.php b/locale/tr-TR/messages.php index afd1a35..8f5993b 100644 --- a/locale/tr-TR/messages.php +++ b/locale/tr-TR/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/uk-UA/messages.php b/locale/uk-UA/messages.php index c91115e..0291688 100644 --- a/locale/uk-UA/messages.php +++ b/locale/uk-UA/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => 'Ласкаво просимо на наш сайт!', 'description' => 'Це опис англійською.', - 'desc' => 'Description', + 'desc' => 'Опис', 'userProfile' => "Профіль користувача", 'user' => 'Користувач', 'home' => 'Домашній екран', @@ -24,7 +24,7 @@ return [ "mixes" => "Змішати", "mix" => "Змішати", "mixNotFound" => "Не вдалось завантажити мікс; або суміш не знайдена, була порожня, або ця суміш приватна.", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "Не вдалося завантажити шоу, або не знайдене змішування, було порожнім, або це змішання є приватним.", "mixName" => "Змішане ім'я", "mixDescription" => "Змішати опис", "mixLength" => "Довжина мікса", @@ -55,17 +55,22 @@ return [ "play" => "Відтворити", "contactus" => "Зв’язатись з нами", "allrightsreserved" => "Усі права захищені.", - "mixshows" => "Mixshows", + "mixshows" => "Змішані серіали", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "Змішане ім'я", + "share" => "Поділитись", + "sahrethismix" => "Поділитися цим мікшуванням", + "sharethismixshow" => "Поділитися цим мікшалом", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "Рік", + "sharetotwitter" => "Поділитись до X (раніше Twitter)", + "sharetofb" => "Поділитись у Facebook", + "sharetoig" => "Поділитися в Instagram", + "copyurl" => "Копіювати посилання", + "urlcopiedtoclipboard" => "URL скопійовано до буферу обміну", + "failedtocopyurl" => "Не вдалося скопіювати URL-адресу", + "name" => "Ім'я", + "username" => "Ім'я користувача", + "logout" => "Вихід із системи", + "upload" => "Вивантажити", ]; \ No newline at end of file diff --git a/locale/vi-VN/messages.php b/locale/vi-VN/messages.php index afd1a35..8f5993b 100644 --- a/locale/vi-VN/messages.php +++ b/locale/vi-VN/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/locale/zh-CN/messages.php b/locale/zh-CN/messages.php index dee6d81..bc363b7 100644 --- a/locale/zh-CN/messages.php +++ b/locale/zh-CN/messages.php @@ -2,7 +2,7 @@ return [ 'welcome' => '欢迎来到我们的网站!', 'description' => '这是英文描述。', - 'desc' => 'Description', + 'desc' => '描述', 'userProfile' => "用户资料", 'user' => '用户', 'home' => '首页', @@ -24,7 +24,7 @@ return [ "mixes" => "混音器", "mix" => "混音器", "mixNotFound" => "无法加载混合物;混合物未找到, 为空, 或者这种混合是私有的。", - "mixshowNotFound" => "Could not load mixshow; either the mixshow wasn't found, was empty, or this mixshow is private.", + "mixshowNotFound" => "无法加载mixshow;要么找不到mixshow,要么是空的,要么这个mixshow是私有的。", "mixName" => "混合名称", "mixDescription" => "混合描述", "mixLength" => "混合长度", @@ -55,17 +55,22 @@ return [ "play" => "播放", "contactus" => "联系我们", "allrightsreserved" => "版权所有。", - "mixshows" => "Mixshows", + "mixshows" => "混合显示", "mixshow" => "Mixshow", - "mixshowName" => "Mixshow Name", - "share" => "Share", - "sahrethismix" => "Share this mix", - "sharethismixshow" => "Share this mixshow", + "mixshowName" => "混合节目名称", + "share" => "分享", + "sahrethismix" => "分享这个组合", + "sharethismixshow" => "分享此 mixshow", "rss" => "RSS", - "year" => "Year", - "sharetotwitter" => "Share to X (formerly Twitter)", - "sharetofb" => "Share to Facebook", - "sharetoig" => "Share to Instagram", - "copyurl" => "Copy URL", - + "year" => "年份", + "sharetotwitter" => "分享到 X (旧的 Twitter)", + "sharetofb" => "分享到 Facebook", + "sharetoig" => "分享到 Instagram", + "copyurl" => "复制 URL", + "urlcopiedtoclipboard" => "URL 已复制到剪贴板", + "failedtocopyurl" => "无法复制 URL", + "name" => "名称", + "username" => "用户名", + "logout" => "注销", + "upload" => "上传", ]; \ No newline at end of file diff --git a/locale/zh-TW/messages.php b/locale/zh-TW/messages.php index afd1a35..8f5993b 100644 --- a/locale/zh-TW/messages.php +++ b/locale/zh-TW/messages.php @@ -67,5 +67,10 @@ return [ "sharetofb" => "Share to Facebook", "sharetoig" => "Share to Instagram", "copyurl" => "Copy URL", - + "urlcopiedtoclipboard" => "URL copied to clipboard", + "failedtocopyurl" => "Failed to copy URL", + "name" => "Name", + "username" => "Username", + "logout" => "Logout", + "upload" => "Upload", ]; \ No newline at end of file diff --git a/login.php b/login.php index abcd515..a372820 100644 --- a/login.php +++ b/login.php @@ -1,15 +1,16 @@ login($email, $password); - if ($result === true) { - // Successful login, redirect to profile page + + // If login() returns an array, the login was successful. + if (is_array($result)) { + SessionManager::setUser([ + 'id' => $result['id'], + 'email' => $result['email'], + 'username' => $result['username'], + 'firstName' => $result['firstName'], + 'lastName' => $result['lastName'], + 'role' => $result['isAdmin'] ? 'admin' : 'user' + ]); header("Location: profile.php"); exit; } else { - // Set error message from login method (includes lockout messages) + // Login failed; $result contains an error message. $_SESSION['error'] = $result; } } } } + require_once 'includes/header.php'; +if (isset($_SESSION['error'])) { + echo ''; + unset($_SESSION['error']); +} + ?> +