@@ -79,15 +79,10 @@ public function request(): bool
7979 */
8080 public static function send (array $ urls ): bool
8181 {
82- if (!Seo::option ('indexnow.enabled ' )) {
82+ if (!Seo::option ('indexnow.enabled ' ) || empty ( $ urls ) ) {
8383 return false ;
8484 }
8585
86- if (empty ($ urls )) {
87- return false ;
88- }
89-
90- $ key = static ::key ();
9186 $ firstUrl = $ urls [0 ];
9287 $ parsedUrl = parse_url ($ firstUrl );
9388 $ host = $ parsedUrl ['host ' ];
@@ -103,46 +98,48 @@ public static function send(array $urls): bool
10398 $ basePath = '' ;
10499 if ($ path && $ path !== '/ ' ) {
105100 // find the base path by comparing with site url
106- $ siteUrl = site ()->url ();
101+ $ siteUrl = $ this -> page -> site ()->url ();
107102 $ siteParsed = parse_url ($ siteUrl );
108103 $ basePath = $ siteParsed ['path ' ] ?? '' ;
109104 }
110105
111106 $ searchEngine = Seo::option ('indexnow.searchEngine ' );
112-
113- // ensure search engine URL is properly formatted
114107 $ searchEngine = rtrim ($ searchEngine , '/ ' );
115108 if (!str_contains ($ searchEngine , '/indexnow ' )) {
116109 $ searchEngine .= '/indexnow ' ;
117110 }
118111
119- // filter urls to only include those from the same domain
120- $ domainUrls = array_filter ($ urls , function ($ url ) use ($ host ) {
121- return parse_url ($ url , PHP_URL_HOST ) === $ host ;
122- });
123-
124- // prepare request data
125- $ data = [
126- 'host ' => $ host ,
127- 'key ' => $ key ,
128- 'keyLocation ' => "{$ scheme }:// {$ host }{$ basePath }/indexnow- {$ key }.txt " ,
129- 'urlList ' => array_values (array_unique ($ domainUrls ))
130- ];
131-
132- try {
133- $ response = Remote::post ($ searchEngine , [
134- 'headers ' => [
135- 'Content-Type ' => 'application/json; charset=utf-8 ' ,
136- 'User-Agent ' => Seo::userAgent ()
137- ],
138- 'data ' => json_encode ($ data )
139- ]);
140-
141- return $ response ->code () === 200 || $ response ->code () === 202 ;
142- } catch (\Exception $ e ) {
143- // log error if needed
144- return false ;
112+ $ domainUrls = array_filter ($ urls , fn ($ url ) => parse_url ($ url , PHP_URL_HOST ) === $ host );
113+
114+ // split into batches of 10,000 (IndexNow limit)
115+ $ batches = array_chunk (array_values (array_unique ($ domainUrls )), 10000 );
116+ $ allSuccessful = true ;
117+ $ key = static ::key ();
118+
119+ foreach ($ batches as $ batch ) {
120+ try {
121+ $ response = Remote::post ($ searchEngine , [
122+ 'headers ' => [
123+ 'Content-Type ' => 'application/json; charset=utf-8 ' ,
124+ 'User-Agent ' => Seo::userAgent ()
125+ ],
126+ 'data ' => json_encode ([
127+ 'host ' => $ host ,
128+ 'key ' => $ key ,
129+ 'keyLocation ' => "{$ scheme }:// {$ host }{$ basePath }/indexnow- {$ key }.txt " ,
130+ 'urlList ' => $ batch
131+ ])
132+ ]);
133+
134+ if ($ response ->code () > 299 ) {
135+ $ allSuccessful = false ;
136+ }
137+ } catch (\Exception $ e ) {
138+ $ allSuccessful = false ;
139+ }
145140 }
141+
142+ return $ allSuccessful ;
146143 }
147144
148145 /**
@@ -296,12 +293,12 @@ protected function collectByTemplates(array $templates): void
296293 {
297294 $ language = App::instance ()->language ();
298295
299- foreach ( $ templates as $ template ) {
300- foreach ( site ()-> index () as $ page ) {
301- if ($ page-> intendedTemplate ()-> name () === $ template && $ this ->isIndexable ($ page )) {
302- $ this -> urls [] = $ page -> url ( $ language ?->code());
303- }
304- }
296+ $ pages = $ this -> page -> site ()-> index ()
297+ -> filterBy ( ' intendedTemplate ' , ' in ' , $ templates )
298+ -> filter ( fn ($ page) => $ this ->isIndexable ($ page ));
299+
300+ foreach ( $ pages as $ page ) {
301+ $ this -> urls [] = $ page -> url ( $ language ?->code());
305302 }
306303 }
307304
0 commit comments