diff --git a/app/Console/Commands/Grap.php b/app/Console/Commands/Grap.php index 3326c900..af297178 100644 --- a/app/Console/Commands/Grap.php +++ b/app/Console/Commands/Grap.php @@ -46,9 +46,10 @@ class Grap extends Command $txt .= '--F force DayTournament links' . PHP_EOL; $txt .= '--c clear grap dir' . PHP_EOL; $txt .= '--m mail only' . PHP_EOL; - $txt .= '--g grap & excel only' . PHP_EOL; - $txt .= '--R read file' . PHP_EOL; - $txt .= '--S save to file' . PHP_EOL; + $txt .= '--C clear folder' . PHP_EOL; + $txt .= '--G grap' . PHP_EOL; + $txt .= '--E make excel' . PHP_EOL; + $txt .= '--M mail' . PHP_EOL; $txt .= '--folder' . PHP_EOL; $txt .= '-----------------------------------------------------------' . PHP_EOL; $txt .= 'FUNCTION' . PHP_EOL; @@ -69,18 +70,20 @@ class Grap extends Command case 1: // DAILY - SetStorage::set(1); - RemoveDir::remove(); - - // with --m just resend mail - if (! self::$options['m']) { + if (self::$options['C']) { Grapper::load(1); + } + + if (self::$options['G']) { + Grapper::load(1); + } + + if (self::$options['E']) { MakeExcel::create(); } - // with --g just grap & excel - if (! self::$options['g']) { + if (self::$options['M']) { SendMail::run(1); } diff --git a/app/Console/Commands/Grapper/Sofascore/Grapper.php b/app/Console/Commands/Grapper/Sofascore/Grapper.php index fc1b5760..3de95cb6 100644 --- a/app/Console/Commands/Grapper/Sofascore/Grapper.php +++ b/app/Console/Commands/Grapper/Sofascore/Grapper.php @@ -13,7 +13,6 @@ use App\Models\SofaScoreTaskTournament; use App\Utilities\Notice; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\File; -use Illuminate\Support\Facades\Storage; class Grapper { @@ -44,16 +43,11 @@ class Grapper default: $active_tournaments = SofaScoreTaskTournament::with('tournament')->where('sofa_score_task_id', $task_id)->where('disabled', false)->get(); + // $active_tournaments = SofaScoreTaskTournament::with('tournament')->where('sofa_score_tournament_id', 247)->where('sofa_score_task_id', $task_id)->where('disabled', false)->get(); break; } - /** - * daily restart always - */ - if (\in_array($task_id, [1, 2])) { - SofaScoreEventGrapped::where('grapper_id', $task_id)->delete(); - } /** * Restart */ @@ -77,22 +71,33 @@ class Grapper DaysTournament::get($day); + dd($active_tournaments); + foreach ($active_tournaments as $tournament) { $res = SofaScoreDayTournament::whereDate('day', '=', $day)->where('tournament_id', $tournament->sofa_score_tournament_id)->first(); if ($res) { - // if ($debug) { - // Notice::note($day, 'g'); - // } + if ($debug) { + Notice::note($tournament->sofa_score_tournament_id, 'bb'); + } + + if (! $force) + Sleeper::rand(1); + else + Sleeper::rand(); + + if ($debug) { + Notice::note($day, 'br'); + } $url = Grap::$options['base_url'] . "api/v1/unique-tournament/$tournament->sofa_score_tournament_id/scheduled-events/$day"; - - Sleeper::rand(1); - $data = CurlSofa::load($url); + Notice::note($data, 'bb'); + + if (isset($data['events'])) { if ($debug) { @@ -102,11 +107,8 @@ class Grapper foreach ($data['events'] as $event) { Grap::$useragent = rand(1, 6); - if (Storage::directoryExists(Grap::$storage . '/' . $day)) { - if ($debug) { - Notice::note('FOLDER - Allready grapped at ' . $day . ' - ' . $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name'], 'g'); - } - } else if (! $force && SofaScoreEventGrapped::where('id', (int) $event['id'])->exists()) { + + if (! $force && SofaScoreEventGrapped::where('grapper_id', $task_id)->where('id', (int) $event['id'])->exists()) { if ($debug) { Notice::note('DB - Allready grapped at ' . $day . ' - ' . $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name'], 'g'); } @@ -118,105 +120,103 @@ class Grapper $starttime = Carbon::createFromTimestamp($event['startTimestamp']); - if ($now->greaterThan($starttime) && $starttime->isSameDay($carbon_day)) { + // dd($starttime); + // if ($now->greaterThan($starttime) && $starttime->isSameDay($carbon_day)) { + + if (! $force) Sleeper::rand(1); - - if ($debug) { - Notice::note($day . ' - ' . $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name'], 'bg'); - } - - $grapped = SofaScoreEventGrapped::firstOrNew(['id' => $event['id']]); - $grapped->grapper_id = $task_id; - $grapped->day = $day; - $grapped->liga = $event['tournament']['name']; - $grapped->name = $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name']; - $grapped->url = $url; - $grapped->starttime = $starttime->toDateTimeString(); - - $folder = strtolower(Grap::$storage . '/' . $day . '/' . $day . '-' . $event['tournament']['category']['slug'] . '-' . $event['tournament']['slug'] . '/' . $event['slug']); - - File::makeDirectory($folder, 0775, true, true); - - /********************************* - * EVENT event - *********************************/ - - File::put($folder . '/event.json', json_encode($event)); - - /********************************* - * EVENT statistics - *********************************/ - - $event_id = $event['id']; - - $url = Grap::$options['base_url'] . "api/v1/event/$event_id/statistics"; - + else Sleeper::rand(); - $data = CurlSofa::load($url); - $data['id'] = $event_id; - - File::put($folder . '/statistics.json', json_encode($data)); - - $grapped->got_statistics = 1; - - /********************************* - * EVENT lineups - *********************************/ - - $url = Grap::$options['base_url'] . "api/v1/event/$event_id/lineups"; - - Sleeper::rand(); - - $data = CurlSofa::load($url); - - $data['id'] = $event_id; - - File::put($folder . '/lineups.json', json_encode($data)); - - $grapped->got_lineups = 1; - - /********************************* - * EVENT odds - *********************************/ - - $url = Grap::$options['base_url'] . "api/v1/event/$event_id/odds/1/all"; - - Sleeper::rand(); - - $data = CurlSofa::load($url); - - $data['id'] = $event_id; - - File::put($folder . '/odds.json', json_encode($data)); - - $grapped->got_odds = 1; - - /********************************* - * EVENT incidents - *********************************/ - - $url = Grap::$options['base_url'] . "api/v1/event/$event_id/incidents"; - - Sleeper::rand(); - - $data = CurlSofa::load($url); - - $data['id'] = $event_id; - - File::put($folder . '/incidents.json', json_encode($data)); - - $grapped->got_incidents = 1; - - $grapped->save(); + if ($debug) { + Notice::note($day . ' - ' . $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name'], 'bg'); } + + $folder = strtolower(Grap::$storage . '/' . $day . '/' . $day . '-' . $event['tournament']['category']['slug'] . '-' . $event['tournament']['slug'] . '/' . $event['slug']); + + File::makeDirectory($folder, 0775, true, true); + + /********************************* + * EVENT event + *********************************/ + + File::put($folder . '/event.json', json_encode($event)); + + /********************************* + * EVENT statistics + *********************************/ + + $event_id = $event['id']; + + $url = Grap::$options['base_url'] . "api/v1/event/$event_id/statistics"; + + Sleeper::rand(); + + $data = CurlSofa::load($url); + + $data['id'] = $event_id; + + File::put($folder . '/statistics.json', json_encode($data)); + + /********************************* + * EVENT lineups + *********************************/ + + $url = Grap::$options['base_url'] . "api/v1/event/$event_id/lineups"; + + Sleeper::rand(); + + $data = CurlSofa::load($url); + + $data['id'] = $event_id; + + File::put($folder . '/lineups.json', json_encode($data)); + + /********************************* + * EVENT odds + *********************************/ + + $url = Grap::$options['base_url'] . "api/v1/event/$event_id/odds/1/all"; + + Sleeper::rand(); + + $data = CurlSofa::load($url); + + $data['id'] = $event_id; + + File::put($folder . '/odds.json', json_encode($data)); + + /********************************* + * EVENT incidents + *********************************/ + + $url = Grap::$options['base_url'] . "api/v1/event/$event_id/incidents"; + + Sleeper::rand(); + + $data = CurlSofa::load($url); + + $data['id'] = $event_id; + + File::put($folder . '/incidents.json', json_encode($data)); + + $grapped = SofaScoreEventGrapped::firstOrNew(['id' => $event['id']]); + $grapped->grapper_id = $task_id; + $grapped->day = $day; + $grapped->liga = $event['tournament']['name']; + $grapped->name = $event['homeTeam']['name'] . ' vs ' . $event['awayTeam']['name']; + $grapped->url = $url; + $grapped->starttime = $starttime->toDateTimeString(); + $grapped->save(); + // } } } } } } + SofaScoreTaskDay::updateOrCreate([ 'grapper_id' => (int) $task_id, 'day' => $day, @@ -227,8 +227,13 @@ class Grapper $count++; if ($debug) { - Notice::note("$count days done", 'p'); + Notice::note("$count days done, sleep 10-20 sec", 'p'); } + + if (! $force) + Sleeper::rand(2); + else + Sleeper::rand(); } } } diff --git a/app/Console/Commands/Grapper/Sofascore/GrapperTest.php b/app/Console/Commands/Grapper/Sofascore/GrapperTest.php index 29d368c4..94fd48b3 100644 --- a/app/Console/Commands/Grapper/Sofascore/GrapperTest.php +++ b/app/Console/Commands/Grapper/Sofascore/GrapperTest.php @@ -4,6 +4,7 @@ namespace App\Console\Commands\Grapper\Sofascore; use App\Console\Commands\Grap; use App\Console\Commands\Grapper\Sofascore\Helper\CurlLivescore; +use App\Console\Commands\Grapper\Sofascore\Helper\CurlSofa; use App\Utilities\Notice; use DOMDocument; use DOMXPath; @@ -19,17 +20,21 @@ class GrapperTest $testfile = 'livescore.txt'; - $path = __DIR__.self::$testfiles.$testfile; + $path = __DIR__ . self::$testfiles . $testfile; - Notice::note('Grapper testing '.$testfile, 'b'); + Notice::note('Grapper testing ' . $testfile, 'b'); - $url = 'https://www.livescore.in/horse-racing/canada/woodbine-2020/'; + // $url = 'https://www.livescore.in/horse-racing/canada/woodbine-2020/'; + $url = 'https://www.sofascore.com/api/v1/event/16298660/statistics'; + + $data = CurlSofa::load($url); + + Notice::note($data, '', 1); if ($read) { Notice::note('data read localy', 'p'); $data = file_get_contents($path); - } else { $data = CurlLivescore::load($url); } @@ -58,7 +63,7 @@ class GrapperTest $teams = $xpath->query("//div[contains(@class, 'event__participant')]"); foreach ($teams as $team) { - echo trim($team->nodeValue).PHP_EOL; + echo trim($team->nodeValue) . PHP_EOL; } Notice::note($data, 'p', 1); diff --git a/app/Console/Commands/Grapper/Sofascore/Helper/CurlSofa.php b/app/Console/Commands/Grapper/Sofascore/Helper/CurlSofa.php index 0fe0c1fc..accd2fe2 100644 --- a/app/Console/Commands/Grapper/Sofascore/Helper/CurlSofa.php +++ b/app/Console/Commands/Grapper/Sofascore/Helper/CurlSofa.php @@ -15,7 +15,13 @@ class CurlSofa if ($debug) { Notice::note($url, 'b'); } - + // $useragents = []; + // $useragents[1] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"; + // $useragents[2] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36"; + // $useragents[3] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3 Safari/605.1.15"; + // $useragents[4] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:135.0) Gecko/20100101 Firefox/135.0"; + // $useragents[5] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"; + // $useragents[6] = "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Mobile Safari/537.36"; $useragents = []; $useragents[1] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2.1 Safari/605.1.15'; $useragents[2] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.3.1 Safari/605.1.15'; @@ -24,13 +30,31 @@ class CurlSofa $useragents[5] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0'; $useragents[6] = 'Mozilla/5.0 (X11; CrOS x86_64 14541.0.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36'; + // GET /api/v1/config/default-unique-tournaments/AT/football HTTP/2 + // Host: www.sofascore.com + // User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:139.0) Gecko/20100101 Firefox/139.0 + // Accept: */* + // Accept-Language: de,en-US;q=0.7,en;q=0.3 + // Accept-Encoding: gzip, deflate, br, zstd + // Referer: https://www.sofascore.com/ + // X-Requested-With: 629800 + // DNT: 1 + // Sec-GPC: 1 + // Connection: keep-alive + // Sec-Fetch-Dest: empty + // Sec-Fetch-Mode: cors + // Sec-Fetch-Site: same-origin + // Priority: u=4 + // Pragma: no-cache + // Cache-Control: no-cache + // TE: trailers $headers = [ 'User-Agent: ' . $useragents[Grap::$useragent], 'Accept: */*', 'Accept-Language: de,en-US;q=0.7,en;q=0.3', 'Accept-Encoding: gzip, deflate, br, zstd', 'Referer: https://www.sofascore.com/', - 'X-Requested-With: 5c6b10', + 'X-Requested-With: 629800', 'DNT: 1', 'Sec-GPC: 1', 'Connection: keep-alive', @@ -48,11 +72,10 @@ class CurlSofa curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); - + // This line magically handles all decompression out-of-the-box: + curl_setopt($ch, CURLOPT_ENCODING, ''); $data = curl_exec($ch); - $data = gzdecode($data); - $data = json_decode($data, true); return $data; diff --git a/app/Console/Commands/Grapper/Sofascore/Helper/LoadDays.php b/app/Console/Commands/Grapper/Sofascore/Helper/LoadDays.php index 4416d077..08f8f382 100644 --- a/app/Console/Commands/Grapper/Sofascore/Helper/LoadDays.php +++ b/app/Console/Commands/Grapper/Sofascore/Helper/LoadDays.php @@ -46,8 +46,8 @@ class LoadDays default: $from = ValidateDate::get($task->day_from); - $to = ValidateDate::get($task->day_to); $from = Carbon::createFromDate($from); + $to = ValidateDate::get($task->day_to); $to = Carbon::createFromDate($to); break; } diff --git a/app/Filament/Pages/PlayerProps.php b/app/Filament/Pages/PlayerProps.php index 4a55c3be..c7420eaa 100644 --- a/app/Filament/Pages/PlayerProps.php +++ b/app/Filament/Pages/PlayerProps.php @@ -55,7 +55,7 @@ class PlayerProps extends Page implements HasForms public ?array $filterData; - public array $lineUpOptinos; + public array $lineUpOptions; public string $activeLineUp = '3313'; @@ -167,7 +167,7 @@ class PlayerProps extends Page implements HasForms ->prefixIconColor('info') ->prefixIcon('icon-soccerfield-fill') ->options(function () { - $res = $this->lineUpOptinos(); + $res = $this->lineUpOptions(); $arr = []; foreach ($res as $key => $value) { if ($this->players && in_array($key, $this->clientLineUps)) { @@ -219,7 +219,7 @@ class PlayerProps extends Page implements HasForms return 5; } - private function lineUpOptinos(): array + private function lineUpOptions(): array { return [ '3313' => '3313', diff --git a/app/Filament/Pages/Statistic.php b/app/Filament/Pages/Statistic.php index 7a63ec67..5c1a7bef 100644 --- a/app/Filament/Pages/Statistic.php +++ b/app/Filament/Pages/Statistic.php @@ -19,15 +19,13 @@ use Filament\Forms\Components\Select; use Filament\Forms\Components\Slider; use Filament\Pages\Dashboard as BaseDashboard; use Filament\Pages\Dashboard\Concerns\HasFiltersForm; +use Filament\Schemas\Components\Actions; use Filament\Schemas\Components\Grid; use Filament\Schemas\Components\Utilities\Get; use Filament\Schemas\Components\Utilities\Set; -// use Filament\Support\Enums\SlideOverPosition; -// use Filament\Support\Enums\Width; use Filament\Schemas\Schema; use Filament\Support\RawJs; use Illuminate\Contracts\Support\Htmlable; -use Illuminate\Contracts\View\View; use Illuminate\Support\HtmlString; class Statistic extends BaseDashboard @@ -139,10 +137,10 @@ class Statistic extends BaseDashboard ->live() ->preload() ->searchable(false) - ->prefixIconColor(fn (Get $get): string => $get('sofascore_category_id') ? 'success' : 'danger') + ->prefixIconColor(fn(Get $get): string => $get('sofascore_category_id') ? 'success' : 'danger') ->prefixIcon('phosphor-globe-fill') ->hiddenLabel() - ->options(fn () => LoadSofaScoreCategory::load()) + ->options(fn() => LoadSofaScoreCategory::load()) ->placeholder('Select Country') ->afterStateUpdated(function (callable $set, $state) { $set('seasonmode', SofaScoreCategory::where('id', $state)->value('season_mode')); @@ -155,10 +153,10 @@ class Statistic extends BaseDashboard Select::make('league_id') ->live() ->preload() - ->prefixIconColor(fn (Get $get): string => $get('league_id') ? 'success' : 'danger') + ->prefixIconColor(fn(Get $get): string => $get('league_id') ? 'success' : 'danger') ->prefixIcon('phosphor-trophy-fill') ->hiddenLabel() - ->options(fn (Get $get) => LoadStatisticFixturesLeaguesOptions::load($get('sofascore_category_id'))) + ->options(fn(Get $get) => LoadStatisticFixturesLeaguesOptions::load($get('sofascore_category_id'))) ->placeholder('Select League') ->afterStateUpdated(function (callable $set) { $set('match_id', null); @@ -169,8 +167,8 @@ class Statistic extends BaseDashboard Select::make('match_id') ->live() ->hiddenLabel() - ->columnSpan(fn (Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) - ->prefixIconColor(fn (Get $get): string => $get('match_id') ? 'success' : 'danger') + ->columnSpan(fn(Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) + ->prefixIconColor(fn(Get $get): string => $get('match_id') ? 'success' : 'danger') ->prefixIcon('phosphor-calendar-check-fill') ->options(function (Get $get) { return LoadStatisticFixturesMatchOptions::load($get('league_id')); @@ -183,10 +181,10 @@ class Statistic extends BaseDashboard ->placeholder('Select Event'), Action::make('esc') ->hiddenLabel() - ->visible(fn (Get $get) => $get('similar_past_matches') != 'none') + ->visible(fn(Get $get) => $get('similar_past_matches') != 'none') ->tooltip('Clear all (esc)') ->icon('phosphor-x-circle') - ->color('gray') + ->color('warning') ->keyBindings(['esc']) ->action('resetFilters'), @@ -203,7 +201,7 @@ class Statistic extends BaseDashboard } }) ->prefixIcon('phosphor-users-three-fill') - ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') ->options(function (Get $get) { if ($get('match_id')) { $res = StatisticFixtures::where('id', $get('match_id'))->first(); @@ -232,9 +230,9 @@ class Statistic extends BaseDashboard Action::make('iconInfo') ->color('success') ->icon('phosphor-question-fill') - ->tooltip(fn () => 'Team Position') + ->tooltip(fn() => 'Team Position') ) - ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') ->default('all') ->selectablePlaceholder(false) ->options([ @@ -289,20 +287,20 @@ class Statistic extends BaseDashboard ->live() // ->columnSpan(2) ->hiddenLabel() - ->columnSpan(fn (Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) + ->columnSpan(fn(Get $get) => $get('similar_past_matches') != 'none' ? 2 : 1) ->suffixAction(Action::make('reset') ->icon('phosphor-x-circle') - ->action(fn (callable $set) => $set('similar_past_matches', 'none')) - ->color(fn (Get $get): string => $get('similar_past_matches') != 'none' ? 'info' : 'gray')) + ->action(fn(callable $set) => $set('similar_past_matches', 'none')) + ->color(fn(Get $get): string => $get('similar_past_matches') != 'none' ? 'info' : 'gray')) ->placeholder('Similar Past Matches') - ->suffix(fn (Get $get): string|HtmlString => $get('similar_past_matches') != 'none' ? new HtmlString('
± '.$get('accuracy').'
') : '') + ->suffix(fn(Get $get): string|HtmlString => $get('similar_past_matches') != 'none' ? new HtmlString('
± ' . $get('accuracy') . '
') : '') ->prefix('SPM') ->prefixAction( Action::make('iconInfo') ->icon('phosphor-question-fill') // ->color(fn(Get $get): string => $get('similar_past_matches') != 'none' ? 'success' : 'primary') ->color('success') - ->tooltip(fn () => $this->tooltip_similar_past_matches()) + ->tooltip(fn() => $this->tooltip_similar_past_matches()) ) ->default('none') ->selectablePlaceholder(false) @@ -322,7 +320,7 @@ class Statistic extends BaseDashboard Slider::make('accuracy') ->live() ->hiddenLabel() - ->hidden(fn (Get $get) => $get('similar_past_matches') == 'none') + ->hidden(fn(Get $get) => $get('similar_past_matches') == 'none') ->fillTrack() ->minValue(0) ->maxValue(0.25) @@ -342,13 +340,13 @@ class Statistic extends BaseDashboard ->allowHtml() ->columnSpan(2) ->placeholder('Player') - ->visible(fn (Get $get) => $get('team_id')) - ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') - ->prefixIconColor(fn (Get $get): string => $get('similar_past_matches') == 'none' ? 'success' : '') + ->visible(fn(Get $get) => $get('team_id')) + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') + ->prefixIconColor(fn(Get $get): string => $get('similar_past_matches') == 'none' ? 'success' : '') ->prefixIcon('icon-player') ->preload() ->searchable() - ->extraAttributes(fn () => [ + ->extraAttributes(fn() => [ 'id' => 'player_selector', 'style' => 'width: 100%;', ]) @@ -356,7 +354,7 @@ class Statistic extends BaseDashboard Action::make('iconInfo') ->icon('phosphor-question-fill') ->color('success') - ->tooltip(fn () => $this->tooltip_player_info()) + ->tooltip(fn() => $this->tooltip_player_info()) ) ->options(function (Get $get) { $team_id = $get('team_id'); @@ -373,7 +371,7 @@ class Statistic extends BaseDashboard ->placeholder('Time on field') ->prefixIcon('phosphor-watch-fill') ->default('all') - ->hidden(fn (Get $get) => ! $get('ss_player_id')) + ->hidden(fn(Get $get) => ! $get('ss_player_id')) ->prefixIconColor('success') ->selectablePlaceholder(false) ->options([ @@ -394,7 +392,7 @@ class Statistic extends BaseDashboard ->extraAttributes([ 'class' => 'radio-statistic-group', ]) - ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') ->columnSpan(2) ->inline() ->default('season') @@ -413,8 +411,8 @@ class Statistic extends BaseDashboard ->multiple() ->placeholder('Current Season') ->prefixIconColor('success') - ->visible(fn (Get $get) => $get('seasonmode')) - ->hidden(fn (Get $get) => $get('seasonmode') == 'halfyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') + ->visible(fn(Get $get) => $get('seasonmode')) + ->hidden(fn(Get $get) => $get('seasonmode') == 'halfyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') ->prefixIcon('phosphor-calendar-star-fill') ->options([ '2026' => '2026', @@ -434,8 +432,8 @@ class Statistic extends BaseDashboard ->multiple() ->placeholder('Current Season') ->prefixIconColor('success') - ->visible(fn (Get $get) => $get('seasonmode')) - ->hidden(fn (Get $get) => $get('seasonmode') == 'fullyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') + ->visible(fn(Get $get) => $get('seasonmode')) + ->hidden(fn(Get $get) => $get('seasonmode') == 'fullyear' || $get('season_or_date') == 'date' || $get('similar_past_matches') != 'none') ->prefixIcon('phosphor-calendar-star-fill') ->options([ '26/27' => '26/27', @@ -451,39 +449,49 @@ class Statistic extends BaseDashboard DatePicker::make('start_date') ->live() ->hiddenLabel() - ->hidden(fn (Get $get) => $get('season_or_date') == 'season') + ->hidden(fn(Get $get) => $get('season_or_date') == 'season') ->native(false) - ->prefixIconColor(fn (Get $get): string => $get('start_date') ? 'success' : 'primary') + ->prefixIconColor(fn(Get $get): string => $get('start_date') ? 'success' : 'primary') ->prefixIcon('phosphor-calendar-fill') ->prefix('Start') ->suffixAction( Action::make('clear_start') ->icon('phosphor-x') ->color('gray') - ->action(fn (Set $set) => $set('start_date', null)) + ->action(fn(Set $set) => $set('start_date', null)) ), DatePicker::make('end_date') ->live() ->hiddenLabel() - ->hidden(fn (Get $get) => $get('season_or_date') == 'season') + ->hidden(fn(Get $get) => $get('season_or_date') == 'season') ->native(false) - ->prefixIconColor(fn (Get $get): string => $get('end_date') ? 'success' : 'primary') + ->prefixIconColor(fn(Get $get): string => $get('end_date') ? 'success' : 'primary') ->prefixIcon('phosphor-calendar-fill') ->prefix('End') ->suffixAction( Action::make('clear_end') ->icon('phosphor-x') ->color('gray') - ->action(fn (Set $set) => $set('end_date', null)) + ->action(fn(Set $set) => $set('end_date', null)) ), - Action::make('esc') - ->hiddenLabel() - ->hidden(fn (Get $get) => $get('similar_past_matches') != 'none') - ->tooltip('Clear all (esc)') - ->icon('phosphor-x-circle') - ->color('gray') - ->keyBindings(['esc']) - ->action('resetFilters'), + Actions::make([ + Action::make('esc') + ->hiddenLabel() + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') + ->tooltip('Clear all (esc)') + ->icon('phosphor-x-circle') + ->color(fn(Get $get) => $get('sofascore_category_id') ? 'warning' : 'gray') + ->keyBindings(['esc']) + ->action('resetFilters'), + Action::make('copy') + ->hiddenLabel() + ->hidden(fn(Get $get) => $get('similar_past_matches') != 'none') + ->visible(fn(Get $get) => $get('team_id')) + ->tooltip('Copy data for pasting into spreadsheet') + ->color('success') + ->icon('phosphor-copy') + ->action('resetFilters'), + ]) ]), ]); } diff --git a/composer.lock b/composer.lock index 3d7ae5ff..601146f5 100644 --- a/composer.lock +++ b/composer.lock @@ -2887,16 +2887,16 @@ }, { "name": "kirschbaum-development/eloquent-power-joins", - "version": "4.3.3", + "version": "4.3.4", "source": { "type": "git", "url": "https://github.com/kirschbaum-development/eloquent-power-joins.git", - "reference": "c609dbbe4ad2051b667e937f1ab554067519d64b" + "reference": "a0e6c0420c381861e1830693c4b74bdac7f7fb5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kirschbaum-development/eloquent-power-joins/zipball/c609dbbe4ad2051b667e937f1ab554067519d64b", - "reference": "c609dbbe4ad2051b667e937f1ab554067519d64b", + "url": "https://api.github.com/repos/kirschbaum-development/eloquent-power-joins/zipball/a0e6c0420c381861e1830693c4b74bdac7f7fb5f", + "reference": "a0e6c0420c381861e1830693c4b74bdac7f7fb5f", "shasum": "" }, "require": { @@ -2944,9 +2944,9 @@ ], "support": { "issues": "https://github.com/kirschbaum-development/eloquent-power-joins/issues", - "source": "https://github.com/kirschbaum-development/eloquent-power-joins/tree/4.3.3" + "source": "https://github.com/kirschbaum-development/eloquent-power-joins/tree/4.3.4" }, - "time": "2026-07-23T11:41:37+00:00" + "time": "2026-09-25T11:10:42+00:00" }, { "name": "laravel/framework", @@ -10229,16 +10229,16 @@ "packages-dev": [ { "name": "barryvdh/laravel-debugbar", - "version": "v4.4.3", + "version": "v4.4.4", "source": { "type": "git", "url": "https://github.com/fruitcake/laravel-debugbar.git", - "reference": "caa08515a2eef6d8137653d3a1f3c3387cadf184" + "reference": "02274537e13944ad1990c521bd06d0fb3578ba17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/caa08515a2eef6d8137653d3a1f3c3387cadf184", - "reference": "caa08515a2eef6d8137653d3a1f3c3387cadf184", + "url": "https://api.github.com/repos/fruitcake/laravel-debugbar/zipball/02274537e13944ad1990c521bd06d0fb3578ba17", + "reference": "02274537e13944ad1990c521bd06d0fb3578ba17", "shasum": "" }, "require": { @@ -10251,7 +10251,7 @@ }, "require-dev": { "larastan/larastan": "^3", - "laravel/ai": "^0.8", + "laravel/ai": "^0.8|^0.9|^0.10|^0.11|^1.0", "laravel/octane": "^2", "laravel/pennant": "^1", "laravel/pint": "^1", @@ -10313,7 +10313,7 @@ ], "support": { "issues": "https://github.com/fruitcake/laravel-debugbar/issues", - "source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.4.3" + "source": "https://github.com/fruitcake/laravel-debugbar/tree/v4.4.4" }, "funding": [ { @@ -10325,7 +10325,7 @@ "type": "github" } ], - "time": "2026-09-01T13:46:43+00:00" + "time": "2026-09-24T10:05:29+00:00" }, { "name": "brianium/paratest", @@ -12303,11 +12303,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.2.14", + "version": "2.2.16", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/9c672e7a8e791dfc3d30e55f683e73fc0b63a3ac", - "reference": "9c672e7a8e791dfc3d30e55f683e73fc0b63a3ac", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/46a6d9060e5a7763adfcc21ebcb8b504ebdbcb92", + "reference": "46a6d9060e5a7763adfcc21ebcb8b504ebdbcb92", "shasum": "" }, "require": { @@ -12363,7 +12363,7 @@ "type": "github" } ], - "time": "2026-09-12T21:39:33+00:00" + "time": "2026-09-25T09:31:51+00:00" }, { "name": "phpunit/php-code-coverage",