Skip to content

Commit a9382e6

Browse files
committed
Added laravel/prompts package to composer.json and updated the default disk setting in fv-sitemap.php. Created InstallCommand.php and SitemapGenerateCommand.php files in the src/Commands directory. Renamed SitemapCommand.php to SitemapGenerateCommand.php. Created SitemapController.php in the src/Http/Controllers directory. Updated SitemapServiceProvider.php to include the new commands and register the SitemapController route.
1 parent 573707b commit a9382e6

File tree

8 files changed

+242
-109
lines changed

8 files changed

+242
-109
lines changed

composer.json

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"require": {
1919
"php": "^8.1",
2020
"illuminate/contracts": "^10.0",
21+
"laravel/prompts": "^0.1.16",
2122
"spatie/laravel-package-tools": "^1.14.0",
2223
"spatie/laravel-sitemap": "^7.2"
2324
},

config/fv-sitemap.php

+3-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
return [
44
/**
55
* Specifies the default filesystem disk that should be used.
6-
* The 'public' disk is typically used for files that need to be publicly accessible to users.
6+
* The 'public_path' disk is typically used for files that need to be publicly accessible to users.
77
* This setting can influence where files, such as generated sitemaps, are stored by default.
88
*/
9-
'disk' => 'public_path',
9+
'disk' => 'public',
1010

1111
/**
1212
* Determines whether the index page should be excluded from the sitemap.
@@ -24,16 +24,14 @@
2424
* An array of route names to be excluded from the sitemap.
2525
* Useful for excluding specific pages that should not be discoverable via search engines.
2626
*/
27-
'sitemap_exclude_route_names' => [
28-
'welcome2',
27+
'exclude_route_names' => [
2928
],
3029

3130
/**
3231
* Specifies paths that should be excluded from the sitemap.
3332
* Any routes starting with these paths will not be included in the sitemap, enhancing control over the sitemap contents.
3433
*/
3534
'exclude_paths' => [
36-
'/posts/',
3735
],
3836

3937
/**

resources/stubs/.gitkeep

Whitespace-only changes.

src/Commands/InstallCommand.php

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace Fuelviews\Sitemap\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use function Laravel\Prompts\select;
7+
use function Laravel\Prompts\confirm;
8+
9+
class InstallCommand extends Command
10+
{
11+
/*
12+
* TODO
13+
*/
14+
public $signature = 'sitemap:install';
15+
16+
/*
17+
* TODO
18+
*/
19+
public $description = 'Sitemap install command';
20+
21+
/*
22+
* TODO
23+
*/
24+
public function handle(): int
25+
{
26+
if (confirm(
27+
label:'Do you want to publish the configuration file?',
28+
)) {
29+
$this->call('vendor:publish', [
30+
'--provider' => "Fuelviews\\Sitemap\\SitemapServiceProvider",
31+
'--tag' => "config"
32+
]);
33+
}
34+
35+
if ($frequency = select(
36+
label: 'How often do you want to generate your sitemap?',
37+
options: ['daily', 'weekly', 'monthly', 'never'],
38+
default: 'weekly'
39+
)) {
40+
$this->insertSitemapGenerationCommand($frequency);
41+
}
42+
43+
if (confirm(
44+
label: 'Would you like to star our repo on GitHub?'
45+
)) {
46+
$this->openInBrowser('https://github.com/fuelviews/laravel-sitemap');
47+
}
48+
49+
return self::SUCCESS;
50+
}
51+
52+
/*
53+
* TODO
54+
*/
55+
protected function insertSitemapGenerationCommand($frequency)
56+
{
57+
if ($frequency === 'never') {
58+
return;
59+
}
60+
61+
$kernelPath = app_path('Console/Kernel.php');
62+
$kernelContents = file_get_contents($kernelPath);
63+
64+
if (strpos($kernelContents, 'sitemap:generate') !== false) {
65+
return;
66+
}
67+
68+
$commandToInsert = " \$schedule->command('sitemap:generate')->$frequency();\n";
69+
70+
$scheduleMethodPos = strpos($kernelContents, 'function schedule(');
71+
if ($scheduleMethodPos === false) {
72+
$this->error('Unable to find the schedule method in Kernel.php.');
73+
return;
74+
}
75+
76+
$insertPos = strpos($kernelContents, '//', $scheduleMethodPos);
77+
if ($insertPos === false) {
78+
$this->error('Unable to find the insertion point in Kernel.php.');
79+
return;
80+
}
81+
82+
$insertPos = strpos($kernelContents, "\n", $insertPos) + 1;
83+
$newKernelContents = substr_replace($kernelContents, $commandToInsert, $insertPos, 0);
84+
85+
if (file_put_contents($kernelPath, $newKernelContents) === false) {
86+
$this->error('Failed to write to Kernel.php.');
87+
return;
88+
}
89+
}
90+
91+
/*
92+
* TODO
93+
*/
94+
protected function openInBrowser($url)
95+
{
96+
switch(PHP_OS_FAMILY) {
97+
case 'Windows':
98+
exec("start " . escapeshellarg($url));
99+
break;
100+
case 'Linux':
101+
exec("xdg-open " . escapeshellarg($url));
102+
break;
103+
case 'Darwin': // macOS
104+
exec("open " . escapeshellarg($url));
105+
break;
106+
default:
107+
$this->error("Platform not supported.");
108+
$this->info("Please visit: $url");
109+
break;
110+
}
111+
}
112+
}

src/Commands/SitemapCommand.php src/Commands/SitemapGenerateCommand.php

+78-78
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
use GuzzleHttp\Exception\GuzzleException;
77
use Illuminate\Console\Command;
88
use Illuminate\Support\Facades\Config;
9-
use Illuminate\Support\Facades\Log;
109
use Illuminate\Support\Facades\Route;
11-
use Illuminate\Support\Facades\Storage;
12-
use Spatie\Crawler\Crawler;
10+
Use Illuminate\Support\Facades\Storage;
11+
use Illuminate\Support\Facades\Log;
1312
use Spatie\Sitemap\SitemapGenerator;
14-
use Spatie\Sitemap\SitemapIndex;
1513
use Spatie\Sitemap\Tags\Url;
14+
use Spatie\Crawler\Crawler;
15+
use Spatie\Sitemap\SitemapIndex;
1616

17-
class SitemapCommand extends Command
17+
class SitemapGenerateCommand extends Command
1818
{
1919
/**
2020
* The name and signature of the console command.
@@ -31,7 +31,12 @@ class SitemapCommand extends Command
3131
* when listed in the console. It's shown when you run `php artisan list`
3232
* or when you specifically view help for this command.
3333
*/
34-
protected $description = 'Generate sitemap';
34+
protected $description = 'Sitemap Generation';
35+
36+
/**
37+
* TODO
38+
*/
39+
protected $diskName;
3540

3641
/**
3742
* Execute the console command.
@@ -44,22 +49,32 @@ class SitemapCommand extends Command
4449
*/
4550
public function handle()
4651
{
47-
$SitemapIndex = ! Config::get('fv-sitemap.exclude_index');
52+
$this->diskName = Config::get('fv-sitemap.disk', 'public');
4853

49-
if ($SitemapIndex) {
50-
$this->generatePagesSitemap();
51-
$this->generatePostsSitemap();
54+
try {
55+
$SitemapIndex = !Config::get('fv-sitemap.exclude_index');
5256

53-
$sitemapIndex = SitemapIndex::create()
54-
->add('/pages_sitemap.xml')
55-
->add('/posts_sitemap.xml');
57+
if ($SitemapIndex) {
58+
$this->generatePagesSitemap();
59+
$this->generatePostsSitemap();
5660

57-
$sitemapIndex->writeToFile(public_path('sitemap.xml'));
58-
} else {
59-
$this->generatePagesSitemap('sitemap.xml');
60-
}
61+
$sitemapIndex = SitemapIndex::create()
62+
->add('/sitemap/pages_sitemap.xml')
63+
->add('/sitemap/posts_sitemap.xml');
6164

62-
$this->info('Sitemap generated successfully.');
65+
$sitemapIndex->writeToDisk($this->diskName, '/sitemap/sitemap.xml', true);
66+
} else {
67+
$this->generatePagesSitemap('/sitemap/sitemap.xml');
68+
}
69+
70+
$this->info('Sitemap generated successfully.');
71+
} catch (\Exception $e) {
72+
Log::error('Sitemap generation failed: ' . $e->getMessage());
73+
74+
$this->error('Sitemap generation failed: ' . $e->getMessage());
75+
76+
return 1;
77+
}
6378
}
6479

6580
/**
@@ -69,14 +84,13 @@ public function handle()
6984
* It filters out URLs based on various criteria, including predefined excluded routes, paths,
7085
* and specific URLs. The resulting sitemap is then saved to a specified filename.
7186
*
72-
* @param string $filename The filename for the generated sitemap, defaulting to 'pages_sitemap.xml'.
87+
* @param string $filename The filename for the generated sitemap, defaulting to 'pages_sitemap.xml'.
7388
*/
7489
protected function generatePagesSitemap($filename = 'pages_sitemap.xml')
7590
{
76-
$diskName = Config::get('fv-sitemap.disk');
77-
$tempFilePath = tempnam(sys_get_temp_dir(), 'sitemap');
78-
79-
$excludedRouteNameUrls = $this->mapExcludedRoutesToUrls();
91+
$filename = 'sitemap/' . $filename;
92+
93+
$excludedRouteNameUrls = $this->mapExcludedRouteNamesToUrls();
8094
$excludedPaths = $this->getExcludedPaths();
8195
$excludedUrls = $this->getExcludedUrls();
8296

@@ -100,23 +114,12 @@ protected function generatePagesSitemap($filename = 'pages_sitemap.xml')
100114
$normalizedUrl = rtrim($url->url, '/');
101115
if ($normalizedUrl !== $baseUrlWithoutSlash) {
102116
$url->setUrl($normalizedUrl);
103-
} elseif ($url->url === $baseUrlWithoutSlash.'/') {
117+
} else if ($url->url === $baseUrlWithoutSlash . '/') {
104118
return null;
105119
}
106120

107121
return $url;
108-
})->getSitemap()->writeToFile($tempFilePath);
109-
110-
$sitemapContent = file_get_contents($tempFilePath);
111-
112-
if ($diskName !== 'public_path') {
113-
Storage::disk($diskName)->put($filename, $sitemapContent);
114-
} else {
115-
file_put_contents(public_path($filename), $sitemapContent);
116-
}
117-
118-
// Remove the temporary file after use
119-
@unlink($tempFilePath);
122+
})->getSitemap()->writeToDisk($this->diskName, $filename, true);
120123
}
121124

122125
/**
@@ -132,41 +135,74 @@ protected function generatePostsSitemap()
132135
//
133136
}
134137

138+
/**
139+
* Determine if a path matches any of the excluded patterns.
140+
*
141+
* @param string $path
142+
* @param array $excludedPatterns
143+
* @return bool
144+
*/
145+
protected function isPathExcluded($path, $excludedPatterns)
146+
{
147+
foreach ($excludedPatterns as $pattern) {
148+
if (preg_match("#^" . preg_quote($pattern, '#') . "#", $path)) {
149+
return true;
150+
}
151+
}
152+
return false;
153+
}
154+
135155
/**
136156
* Check if a given URL is a redirect.
137157
*
138-
* @param string $url
158+
* @param string $url
139159
* @return bool
140160
*/
141161
protected function isRedirect($url)
142162
{
143163
$excludeRedirects = Config::get('fv-sitemap.exclude_redirects');
144164

145-
if (! $excludeRedirects) {
165+
if (!$excludeRedirects) {
146166
return false;
147167
}
148168

149169
$client = new Client();
150170
try {
151171
$response = $client->request('HEAD', $url, ['allow_redirects' => false]);
152172
$statusCode = $response->getStatusCode();
153-
154173
return in_array($statusCode, [301, 302, 307, 308]);
155174
} catch (GuzzleException $e) {
156-
Log::error('Error checking URL: '.$e->getMessage());
157-
175+
Log::error('Error checking URL: ' . $e->getMessage());
158176
return false;
159177
}
160178
}
161179

180+
/**
181+
* Map excluded route names to their URLs, excluding any that are invalid.
182+
*
183+
* @return array
184+
*/
185+
protected function mapExcludedRouteNamesToUrls()
186+
{
187+
$excludedRouteNames = $this->getExcludedRouteNames();
188+
189+
return collect($excludedRouteNames)->map(function ($routeName) {
190+
try {
191+
return route($routeName, [], false);
192+
} catch (\InvalidArgumentException $e) {
193+
return null;
194+
}
195+
})->filter()->values()->all();
196+
}
197+
162198
/**
163199
* Get route names to exclude from the sitemap.
164200
*
165201
* @return array
166202
*/
167203
protected function getExcludedRouteNames()
168204
{
169-
return Config::get('fv-sitemap.sitemap_exclude_route_names', []);
205+
return Config::get('fv-sitemap.exclude_route_names', []);
170206

171207
}
172208

@@ -189,40 +225,4 @@ protected function getExcludedUrls()
189225
{
190226
return Config::get('fv-sitemap.exclude_urls', []);
191227
}
192-
193-
/**
194-
* Map excluded route names to their URLs, excluding any that are invalid.
195-
*
196-
* @return array
197-
*/
198-
protected function mapExcludedRoutesToUrls()
199-
{
200-
$excludedRouteNames = $this->getExcludedRouteNames();
201-
202-
return collect($excludedRouteNames)->map(function ($routeName) {
203-
try {
204-
return route($routeName, [], false);
205-
} catch (\InvalidArgumentException $e) {
206-
return null;
207-
}
208-
})->filter()->values()->all();
209-
}
210-
211-
/**
212-
* Determine if a path matches any of the excluded patterns.
213-
*
214-
* @param string $path
215-
* @param array $excludedPatterns
216-
* @return bool
217-
*/
218-
protected function isPathExcluded($path, $excludedPatterns)
219-
{
220-
foreach ($excludedPatterns as $pattern) {
221-
if (preg_match('#^'.preg_quote($pattern, '#').'#', $path)) {
222-
return true;
223-
}
224-
}
225-
226-
return false;
227-
}
228228
}

0 commit comments

Comments
 (0)