belongsToMany('App\Playlist'); } public function scopeInRandomOrderSeeded($query, $id = 0) { $seed = ((intval(now()->unix()/600) . $id)%100000)/100000; DB::query()->selectRaw("SETSEED($seed)")->get(); $query->inRandomOrder(); } public static function whereVerse($passage) { $parser = new BiblePassageParser(); // Can throw an exception. $refs = $parser->parse($passage); $bc = explode(':', $refs[0])[0]; return Song::where('verse', 'LIKE', "$bc:%")->orWhere('verse',"$bc")->orWhere('verse','like',$refs[0].";%")->orWhere('verse', 'LIKE', "%; $bc:%"); } public function getPassagesAttribute() { $parser = new BiblePassageParser(); $refs = $parser->parse($this->verse); return $refs; } public static function passageSort($a, $b) { try { return $a->passages[0]->from()->integerNotation() <=> $b->passages[0]->from()->integerNotation(); } catch (\Exception $e) { // I don't care. } return 0; } public function textTranspose($key) { $sc = new SongController(); $transp = $key; if ($key && $this->plain_key){ $try = $sc->keydiff($this->plain_key, $key); if ($try !== null){ $transp = $try; } } return $sc->transposeBlock($this->text, $transp); } public function setKeyAttribute($value) { if (!$value) return $this->attributes['key'] = null; if ($value[0]>="A"&&$value[0]<="G"){ $this->attributes['key'] = $value; } else { throw new \Exception("Invalid key: $value"); } } public function getNameAttribute() { return $this->title . ( $this->author ? " ($this->author)" : "" ) . ($this->plain_key ? " ($this->plain_key)" : "") . ($this->verse ? " ($this->verse)" : ""); } public function getPlainKeyAttribute() { // TODO: Validate that this is plain. return trim($this->key, "m"); } public function getTextAttribute($text) { return $text ?: file_get_contents("public/text/{$this->id}.txt"); } public function setTextAttribute($text) { // Watch out, this saves immediately! if ($text && $this->id) { file_put_contents("public/text/{$this->id}.txt", $text); } } public function setVerseAttribute($text) { if (!$text) return $this->attributes['verse'] = null; $parser = new BiblePassageParser(); // Can throw an exception. return $this->attributes['verse'] = implode("; ", $parser->parse($text)); } public function getChordsAttribute($txt = null) { $txt = $txt ?? $this->text; $txt = str_replace(['(',')',"\n", "\r"]," ",$txt); $words = explode(' ', $txt); $wordsT = array_map(['self','chordTransform'], $words); $wordsTKey = array_flip($wordsT); $allChords = json_decode(file_get_contents("public/js/chordsdata/chords.json"), TRUE); $chords = array_intersect_key($allChords, $wordsTKey); // TODO: Replace keys from $chords with values from $words. return $chords; } public function getAudioAttribute() { if (file_exists("public/music/{$this->id}.mp3")) { return "/public/music/{$this->id}.mp3"; } elseif (file_exists("public/music/{$this->id}.m4a")) { return "/public/music/{$this->id}.m4a"; } } public static function chordTransform($chord) { $repl = [ 'sus' => 's', 's4' => 's', 's' => 'sus', '7sus' => 'sus7', 'mj7' => 'maj7', '/A' => '/a', '/B' => '/b', '/C' => '/c', '/D' => '/d', '/E' => '/e', '/F' => '/f', '/G' => '/g', '♯' => '#', '♭' => 'b', 'Db' => 'C#', 'Eb' => 'D#', 'Gb' => 'F#', 'Ab' => 'G#', 'Bb' => 'A#', ]; return str_replace(array_keys($repl), array_values($repl), $chord); } }