the browser-facing portion of osu!
at master 6.9 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Models; 7 8use App\Libraries\Commentable; 9use Carbon\Carbon; 10 11/** 12 * @property bool $allow_bancho 13 * @property int $allow_ranking 14 * @property int $build_id 15 * @property \Illuminate\Database\Eloquent\Collection $changelogEntries ChangelogEntry 16 * @property \Illuminate\Database\Eloquent\Collection $changelogs Changelog 17 * @property string $commentable_identifier 18 * @property Comment $comments 19 * @property \Carbon\Carbon $date 20 * @property mixed|null $hash 21 * @property mixed|null $last_hash 22 * @property \Illuminate\Database\Eloquent\Collection $propagationHistories BuildPropagationHistory 23 * @property int|null $stream_id 24 * @property int $test_build 25 * @property UpdateStream $updateStream 26 * @property int $users 27 * @property string|null $version 28 */ 29class Build extends Model implements Commentable 30{ 31 use Traits\CommentableDefaults; 32 33 public $timestamps = false; 34 35 protected $table = 'osu_builds'; 36 protected $primaryKey = 'build_id'; 37 38 protected $casts = [ 39 'allow_bancho' => 'boolean', 40 'date' => 'datetime', 41 ]; 42 43 private $cache = []; 44 45 public static function importFromGithubNewRelease($data) 46 { 47 $repository = Repository::where([ 48 'name' => $data['repository']['full_name'], 49 'build_on_release' => true, 50 ])->first(); 51 52 // abort on unknown or non-auto build repository 53 if ($repository === null) { 54 return; 55 } 56 57 $tag = explode('-', $data['release']['tag_name']); 58 $version = $tag[0]; 59 $streamName = $tag[1] ?? null; 60 61 if ($streamName !== null) { 62 $stream = UpdateStream::where('name', '=', $streamName)->first(); 63 } 64 65 if (!isset($stream)) { 66 $stream = $repository->mainUpdateStream; 67 } 68 69 if (!isset($stream)) { 70 return; 71 } 72 73 $build = $stream->builds()->firstOrCreate([ 74 'version' => $version, 75 ]); 76 77 $lastChange = Carbon::parse($data['release']['created_at']); 78 79 $changelogEntry = new ChangelogEntry(); 80 81 $newChangelogEntryIds = $stream 82 ->changelogEntries() 83 ->orphans($stream->getKey()) 84 ->where($changelogEntry->qualifyColumn('created_at'), '<=', $lastChange) 85 ->pluck($changelogEntry->qualifyColumn('id')); 86 87 $build->changelogEntries()->attach($newChangelogEntryIds); 88 89 return $build; 90 } 91 92 public function updateStream() 93 { 94 return $this->belongsTo(UpdateStream::class, 'stream_id', 'stream_id'); 95 } 96 97 // FIXME: Need to match stream_id as well. It's currently checked in transformer. 98 public function changelogs() 99 { 100 return $this->hasMany(Changelog::class, 'build', 'version'); 101 } 102 103 public function defaultChangelogs() 104 { 105 return $this->changelogs()->default(); 106 } 107 108 public function changelogEntries() 109 { 110 return $this->belongsToMany(ChangelogEntry::class, null, 'build_id'); 111 } 112 113 public function defaultChangelogEntries() 114 { 115 return $this->changelogEntries()->default(); 116 } 117 118 public function scopeDefault($query) 119 { 120 $query->whereIn('stream_id', $GLOBALS['cfg']['osu']['changelog']['update_streams']); 121 } 122 123 public function propagationHistories() 124 { 125 return $this->hasMany(BuildPropagationHistory::class); 126 } 127 128 public function scopePropagationHistory($query) 129 { 130 $query->default()->where('allow_bancho', true); 131 } 132 133 public function scopeSearch($query, $params) 134 { 135 if (isset($params['stream'])) { 136 $stream = UpdateStream::where('name', '=', $params['stream'])->first(); 137 138 if ($stream === null) { 139 return $query->none(); 140 } 141 142 $query->where('stream_id', '=', $stream->getKey()); 143 } else { 144 $stream = null; 145 } 146 147 if (isset($params['from'])) { 148 $query->where('build_id', '>=', function ($q) use ($params, $stream) { 149 $q->from($this->getTable()) 150 ->where('version', '=', $params['from']) 151 ->select('build_id') 152 ->limit(1); 153 154 if ($stream !== null) { 155 $q->where('stream_id', '=', $stream->getKey()); 156 } 157 }); 158 } 159 160 if (isset($params['to'])) { 161 $query->where('build_id', '<=', function ($q) use ($params, $stream) { 162 $q->from($this->getTable()) 163 ->where('version', '=', $params['to']) 164 ->select('build_id') 165 ->limit(1); 166 167 if ($stream !== null) { 168 $q->where('stream_id', '=', $stream->getKey()); 169 } 170 }); 171 } 172 173 if (isset($params['max_id'])) { 174 $query->where('build_id', '<=', $params['max_id']); 175 } 176 177 if (isset($params['limit'])) { 178 $query->limit($params['limit']); 179 } 180 } 181 182 public function commentLocked(): bool 183 { 184 return false; 185 } 186 187 public function commentableTitle() 188 { 189 if ($this->stream_id === null || $this->updateStream === null) { 190 return $this->displayVersion(); 191 } 192 193 return "{$this->updateStream->pretty_name} {$this->displayVersion()}"; 194 } 195 196 public function notificationCover() 197 { 198 // no image 199 } 200 201 public function platform(): string 202 { 203 $version = $this->version; 204 $suffixPos = strpos($version, '-'); 205 206 return $suffixPos === false 207 ? '' 208 : substr($version, $suffixPos + 1); 209 } 210 211 public function url() 212 { 213 return build_url($this); 214 } 215 216 public function versionNext() 217 { 218 if (!array_key_exists('versionNext', $this->cache)) { 219 $this->cache['versionNext'] = static 220 ::default() 221 ->where('build_id', '>', $this->build_id) 222 ->where('stream_id', $this->stream_id) 223 ->orderBy('build_id', 'ASC') 224 ->first(); 225 } 226 227 return $this->cache['versionNext']; 228 } 229 230 public function versionPrevious() 231 { 232 if (!array_key_exists('versionPrevious', $this->cache)) { 233 $this->cache['versionPrevious'] = static 234 ::default() 235 ->where('build_id', '<', $this->build_id) 236 ->where('stream_id', $this->stream_id) 237 ->orderBy('build_id', 'DESC') 238 ->first(); 239 } 240 241 return $this->cache['versionPrevious']; 242 } 243 244 public function displayVersion() 245 { 246 return preg_replace('#[^0-9.]#', '', $this->version); 247 } 248}