From: Vincent Vanwaelscappel Date: Tue, 9 Sep 2025 13:51:06 +0000 (+0200) Subject: wait #7697 @7 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=b3ac69c21a80df3ea816e6fa5e537f62aa70efe2;p=fluidbook-toolbox.git wait #7697 @7 --- diff --git a/app/Http/Controllers/Admin/CrudController.php b/app/Http/Controllers/Admin/CrudController.php index ccc8f6c7f..1a5592601 100644 --- a/app/Http/Controllers/Admin/CrudController.php +++ b/app/Http/Controllers/Admin/CrudController.php @@ -7,18 +7,15 @@ class CrudController extends \Cubist\Backpack\Magic\Controllers\CubistMagicContr use \Cubist\Backpack\Magic\Operations\CreateOperation; use \Cubist\Backpack\Http\Controllers\Operations\CloneEditOperation; use \Backpack\CRUD\app\Http\Controllers\Operations\UpdateOperation; - use \Cubist\Backpack\Http\Controllers\Operations\BulkPublishOperation; use \Backpack\CRUD\app\Http\Controllers\Operations\CloneOperation; - use \Backpack\CRUD\app\Http\Controllers\Operations\BulkCloneOperation; use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation; - use \Backpack\CRUD\app\Http\Controllers\Operations\BulkDeleteOperation; /* */ - protected $_modelNamespace = 'App\Models\Base\ToolboxHRModel'; + protected $_modelNamespace = 'App\Models\Badges\Base'; protected $_routeURL = ''; protected $_singular = ''; protected $_plural = ''; diff --git a/app/Http/Controllers/Admin/FluidbookExternalInstallServerCrudController.php b/app/Http/Controllers/Admin/FluidbookExternalInstallServerCrudController.php index c7e04d7d3..eb062ec6e 100644 --- a/app/Http/Controllers/Admin/FluidbookExternalInstallServerCrudController.php +++ b/app/Http/Controllers/Admin/FluidbookExternalInstallServerCrudController.php @@ -13,6 +13,7 @@ class FluidbookExternalInstallServerCrudController extends \Cubist\Backpack\Magi use \Backpack\CRUD\app\Http\Controllers\Operations\DeleteOperation; use \Backpack\CRUD\app\Http\Controllers\Operations\BulkDeleteOperation; use \App\Http\Controllers\Admin\Operations\ServerOperation; + use \App\Http\Controllers\Admin\Operations\ChangeownerOperation; diff --git a/app/Http/Controllers/Admin/FluidbookPublicationCrudController.php b/app/Http/Controllers/Admin/FluidbookPublicationCrudController.php index 53ccafe7f..0a2987544 100644 --- a/app/Http/Controllers/Admin/FluidbookPublicationCrudController.php +++ b/app/Http/Controllers/Admin/FluidbookPublicationCrudController.php @@ -15,16 +15,18 @@ class FluidbookPublicationCrudController extends \Cubist\Backpack\Magic\Controll use \App\Http\Controllers\Admin\Operations\FluidbookPublication\CloneOperation; use \App\Http\Controllers\Admin\Operations\FluidbookPublication\DeletefbOperation; use \App\Http\Controllers\Admin\Operations\FluidbookPublication\EditOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\MarkdownOperation; - use \App\Http\Controllers\Admin\Operations\ChangeownerOperation; - use \App\Http\Controllers\Admin\Operations\ChangestatusOperation; - use \App\Http\Controllers\Admin\Operations\InvoiceOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\SettingsExportOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\SocialImageOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\ExportPdfOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\GetPageFromWebsiteOperation; - use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\BastideOperation; - + use \App\Http\Controllers\Admin\Operations\ChangeownerOperation; + use \App\Http\Controllers\Admin\Operations\ChangestatusOperation; + use \App\Http\Controllers\Admin\Operations\InvoiceOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\SettingsExportOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\MarkdownOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\SocialImageOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\ExportPdfOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\GetPageFromWebsiteOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\FormOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\BastideOperation; + use \App\Http\Controllers\Admin\Operations\FluidbookPublication\Services\PumaOperation; + /* diff --git a/app/Http/Controllers/Admin/Operations/FluidbookCollection/SettingsExportOperation.php b/app/Http/Controllers/Admin/Operations/FluidbookCollection/SettingsExportOperation.php index 45eff15d0..be763a1b6 100644 --- a/app/Http/Controllers/Admin/Operations/FluidbookCollection/SettingsExportOperation.php +++ b/app/Http/Controllers/Admin/Operations/FluidbookCollection/SettingsExportOperation.php @@ -17,7 +17,6 @@ trait SettingsExportOperation protected function setupSettingsRoutes($segment, $routeName, $controller) { Route::match(['get', 'post'], $segment . '/{id}/download_settings', $controller . '@collectionSettings')->name("download_settings_by_ids"); - Route::match(['post'], $segment . '/search', $controller . '@search'); } protected function collectionSettings($id) @@ -37,70 +36,4 @@ trait SettingsExportOperation return response()->download($file, 'settings_export.xlsx')->deleteFileAfterSend(); } - - protected function connectToSearchServer($id) { - $apiKey = FluidbookCollection::where('id', $id)->get('api_key')->toArray()[0]['api_key']; - $host = FluidbookCollection::where('id', $id)->get('server_search_host')->toArray()[0]['server_search_host']; - - return new Client( - [ - 'api_key' => $apiKey, - 'nodes' => [ - [ - 'host' => $host, // For Typesense Cloud use xxx.a1.typesense.net - 'port' => '',// For Typesense Cloud use 443 - 'protocol' => 'https',// For Typesense Cloud use https - ], - ], - 'connection_timeout_seconds' => 3600, - ] - ); - } - - protected function indexContent($publications, $id) { - $client = $this->connectToSearchServer($id); - - $texts = []; - $content = ''; - - foreach ($publications as $publication) { - $book_id = $publication['fluidbook']; - $fb = FluidbookPublication::find($book_id); - $pages = $fb->getPagesNumber(); - $ref = $fb->reference; - - for($i = 1; $i <= $pages; $i++) { - $getContent = file_get_contents($fb->getTextFile($i)); - if(in_array('gz', explode('.', $fb->getTextFile($i)))) { - $content .= gzdecode($getContent); - }else { - $content .= $getContent; - } - $content .= ' '; - } - - $texts[$book_id] = [ - "text" => $content, - "id" => $book_id, - "reference" => $ref ?? '-' - ]; - $content = ''; - } - - $booksSchema = [ - "name" => "fluidbooks", - "fields" => [ - ["name"=> ".*", "type"=> "auto"] - ] - ]; - - $client->collections['fluidbooks']->delete(); - - $client->collections->create($booksSchema); - $this->addContent($client, $texts); - } - - protected function addContent($client, $content) { - $client->collections["fluidbooks"]->documents->import($content, ['action' => 'create']); - } } diff --git a/app/Jobs/FluidbookCollectionRefreshIndex.php b/app/Jobs/FluidbookCollectionRefreshIndex.php new file mode 100644 index 000000000..b0042b991 --- /dev/null +++ b/app/Jobs/FluidbookCollectionRefreshIndex.php @@ -0,0 +1,24 @@ +collection = $collection; + } + + public function handle() + { + if (!($this->collection instanceof FluidbookCollection)) { + $this->collection = FluidbookCollection::withoutGlobalScopes()->find($this->collection); + } + $this->collection->refreshIndex(); + } +} diff --git a/app/Models/FluidbookCollection.php b/app/Models/FluidbookCollection.php index e26830196..a775b61b0 100644 --- a/app/Models/FluidbookCollection.php +++ b/app/Models/FluidbookCollection.php @@ -9,6 +9,7 @@ use App\Http\Controllers\Admin\Operations\ChangestatusOperation; use App\Http\Controllers\Admin\Operations\FluidbookCollection\DownloadOperation; use App\Http\Controllers\Admin\Operations\FluidbookCollection\PreviewOperation; use App\Http\Controllers\Admin\Operations\FluidbookCollection\SettingsExportOperation; +use App\Jobs\FluidbookCollectionRefreshIndex; use App\Models\Base\ToolboxDownloadable; use App\Jobs\RefreshUsersTree; use App\Models\Base\ToolboxStatusModel; @@ -20,14 +21,20 @@ use Cubist\Backpack\Magic\Fields\BunchOfFieldsMultiple; use Cubist\Backpack\Magic\Fields\Checkbox; use Cubist\Backpack\Magic\Fields\ExternalPath; use Cubist\Backpack\Magic\Fields\FilesOrURL; +use Cubist\Backpack\Magic\Fields\FormSeparator; use Cubist\Backpack\Magic\Fields\Hidden; use Cubist\Backpack\Magic\Fields\Integer; use Cubist\Backpack\Magic\Fields\SelectFromArray; use Cubist\Backpack\Magic\Fields\Text; use Cubist\Util\Files\Files; +use Cubist\Util\Gzip; +use Http\Client\Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Auth; +use Typesense\Client; +use Typesense\Exceptions\ConfigError; +use Typesense\Exceptions\TypesenseClientError; // __('!! Collections de fluidbooks') class FluidbookCollection extends ToolboxStatusModel @@ -81,14 +88,17 @@ class FluidbookCollection extends ToolboxStatusModel $this->addField('version', FluidbookExportVersion::class, __('Version'), ['when' => ['type' => 'export']]); $excluded = array_diff(array_keys(FluidbookExportVersion::getVersions()), ['online', 'sharepoint']); $this->addField('version_multilang', FluidbookExportVersion::class, __('Version'), ['when' => ['type' => 'export_multilang'], 'excluded_options' => $excluded, 'default' => 'online']); - $this->addField('publications', BunchOfFieldsMultiple::class, __('Publications'), ['bunch' => CollectionPublication::class, 'edit_label' => '%fluidbook > %dir']); + $this->addField('install', ExternalPath::class, 'Installer sur un serveur externe', ['default' => '', 'fake' => true, 'translatable' => false, 'store_in' => 'settings', 'servers_model' => FluidbookExternalInstallServer::class, ['when' => ['type' => ['export', 'export_multilang']]]]); $this->addField('override_settings', BunchOfFieldsMultiple::class, __('Redéfinir les paramètres lors de l\'export'), ['bunch' => Fluidbook_Setting::class]); $this->addField('linksAssets', FilesOrURL::class, __('Charger ou remplacer des assets sur tous les fluidbooks de la collection'), ['hint' => __('Cela écrasera les fichiers sur tous les fluidbooks de la collection si ils portent le même nom d\'un asset chargé ici')]); $this->addField('visits_counter', Integer::class, 'Compteur de visites', ['can' => 'fluidbook-collection:write', 'read_only' => true, 'default' => 0, 'column' => true, 'column_label' => '', 'searchLogic' => false]); - $this->addField('type_index', Text::class, __('Type d\'index')); - $this->addField('server_search_host', Text::class, __('Hôte du serveur de recherche')); - $this->addField('api_key', Text::class, __('Clé API')); + $this->addField('sep_search', FormSeparator::class); + $this->addField('search', SelectFromArray::class, __('Indexer les contenus dans un moteur de recherche'), ['options' => ['none' => __('Non'), 'typesense' => __('Serveur typesense')]]); + $this->addField('search_host', Text::class, __('Hôte'), ['when' => ['search' => 'typesense']]); + $this->addField('search_key', Text::class, __('Clé API'), ['when' => ['search' => 'typesense']]); + $this->addField('sep_pubs', FormSeparator::class); + $this->addField('publications', BunchOfFieldsMultiple::class, __('Publications'), ['bunch' => CollectionPublication::class, 'edit_label' => '%fluidbook > %dir']); } @@ -178,4 +188,77 @@ class FluidbookCollection extends ToolboxStatusModel RefreshUsersTree::dispatchSync(); } + + /** + * @throws ConfigError + */ + protected function _connectToSearchServer(): Client + { + $apiKey = $this->search_key; + $host = $this->search_host; + + return new Client( + [ + 'api_key' => $apiKey, + 'nodes' => [ + [ + 'host' => $host, // For Typesense Cloud use xxx.a1.typesense.net + 'port' => '',// For Typesense Cloud use 443 + 'protocol' => 'https',// For Typesense Cloud use https + ], + ], + 'connection_timeout_seconds' => 3600, + ] + ); + } + + /** + * @throws Exception + * @throws TypesenseClientError + * @throws ConfigError + * @throws \JsonException + */ + public function refreshIndex() + { + if (!$this->search === 'none') { + dddd(':/'); + return; + } + + + $texts = []; + foreach ($this->publications as $publication) { + $book_id = $publication['fluidbook']; + /** @var FluidbookPublication $fb */ + $fb = FluidbookPublication::withoutGlobalScopes()->find($book_id); + if (null === $fb) { + continue; + } + + $texts[$book_id] = [ + "text" => $fb->getFullText(), + "id" => $book_id, + "reference" => $fb->reference ?? '-' + ]; + } + + $booksSchema = [ + "name" => "fluidbooks", + "fields" => [ + ["name" => ".*", "type" => "auto"] + ] + ]; + + $client = $this->_connectToSearchServer(); + $client->collections['fluidbooks']->delete(); + $client->collections->create($booksSchema); + $client->collections["fluidbooks"]->documents->import($texts, ['action' => 'create']); + } + + public function onSaved(): bool + { + $res = parent::onSaved(); + dispatch(new FluidbookCollectionRefreshIndex($this->id)); + return $res; + } } diff --git a/app/Models/FluidbookPublication.php b/app/Models/FluidbookPublication.php index a9637bd55..25f4b2b9c 100644 --- a/app/Models/FluidbookPublication.php +++ b/app/Models/FluidbookPublication.php @@ -65,6 +65,7 @@ use Cubist\Util\ArrayUtil; use Cubist\Util\CommandLine\Rsync; use Cubist\Util\Files\Files; use Cubist\Util\Graphics\Image; +use Cubist\Util\Gzip; use Cubist\Util\Json; use Cubist\Util\Str; use Datetime; @@ -481,7 +482,7 @@ class FluidbookPublication extends ToolboxStatusModel foreach ($this->getComposition() as $page => $d) { try { $json['pages'][$page] = file_get_contents($this->getAccessibleFile($page)); - }catch (\Exception $e) { + } catch (\Exception $e) { dump($page, $e->getMessage()); } } @@ -651,6 +652,34 @@ class FluidbookPublication extends ToolboxStatusModel return ($this->transparentPage ? 'png' : $this->imageFormat) ?: 'jpg'; } + public function getFullText() + { + $cacheFile = Files::mkdir($this->protected_path('fluidbookpublication/cache/fulltext/')) . $this->id . '.txt'; + $pages = $this->getPagesNumber(); + $refresh = false; + if (!Gzip::file_exists($cacheFile) || ($cacheFileMtime = Gzip::filemtime($cacheFile)) < $this->getCompositionUpdate()) { + $refresh = true; + } + if (!$refresh) { + for ($i = 1; $i <= $pages; $i++) { + if (Gzip::filemtime($this->getTextFile($i)) > $cacheFileMtime) { + $refresh = true; + break; + } + } + } + + if (!$refresh) { + return Gzip::file_get_contents($cacheFile); + } + $res = ''; + for ($i = 1; $i <= $pages; $i++) { + $res .= Gzip::file_get_contents($this->getTextFile($i)); + } + Gzip::file_put_contents($cacheFile, $res); + return $res; + } + public function protected_path($path, $forceRegion = null) { $r = $forceRegion ?? $this->region; diff --git a/composer.json b/composer.json index 719345b16..8144b0998 100644 --- a/composer.json +++ b/composer.json @@ -70,6 +70,7 @@ "simplesoftwareio/simple-qrcode": "^4.2", "symfony/http-client": "^v6.4.0", "theafolayan/listmonk-laravel": "^1.3", + "typesense/typesense-php": "^5.1", "voku/simple_html_dom": "^4.8" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 1c1a145b3..9da6d518a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0f3f27cdcd5953aa6c227e51d5c5b3b4", + "content-hash": "c0ba0973d873ef25b9b2aa81b60bc007", "packages": [ { "name": "archtechx/enums", @@ -2962,16 +2962,16 @@ }, { "name": "doctrine/dbal", - "version": "3.10.1", + "version": "3.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "3626601014388095d3af9de7e9e958623b7ef005" + "reference": "c6c16cf787eaba3112203dfcd715fa2059c62282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/3626601014388095d3af9de7e9e958623b7ef005", - "reference": "3626601014388095d3af9de7e9e958623b7ef005", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/c6c16cf787eaba3112203dfcd715fa2059c62282", + "reference": "c6c16cf787eaba3112203dfcd715fa2059c62282", "shasum": "" }, "require": { @@ -2987,10 +2987,10 @@ }, "require-dev": { "doctrine/cache": "^1.11|^2.0", - "doctrine/coding-standard": "13.0.0", + "doctrine/coding-standard": "13.0.1", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "2.1.17", + "phpstan/phpstan": "2.1.22", "phpstan/phpstan-strict-rules": "^2", "phpunit/phpunit": "9.6.23", "slevomat/coding-standard": "8.16.2", @@ -3056,7 +3056,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.10.1" + "source": "https://github.com/doctrine/dbal/tree/3.10.2" }, "funding": [ { @@ -3072,7 +3072,7 @@ "type": "tidelift" } ], - "time": "2025-08-05T12:18:06+00:00" + "time": "2025-09-04T23:51:27+00:00" }, { "name": "doctrine/deprecations", @@ -10130,20 +10130,20 @@ }, { "name": "ramsey/uuid", - "version": "4.9.0", + "version": "4.9.1", "source": { "type": "git", "url": "https://github.com/ramsey/uuid.git", - "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0" + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ramsey/uuid/zipball/4e0e23cc785f0724a0e838279a9eb03f28b092a0", - "reference": "4e0e23cc785f0724a0e838279a9eb03f28b092a0", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/81f941f6f729b1e3ceea61d9d014f8b6c6800440", + "reference": "81f941f6f729b1e3ceea61d9d014f8b6c6800440", "shasum": "" }, "require": { - "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13", + "brick/math": "^0.8.8 || ^0.9 || ^0.10 || ^0.11 || ^0.12 || ^0.13 || ^0.14", "php": "^8.0", "ramsey/collection": "^1.2 || ^2.0" }, @@ -10202,9 +10202,9 @@ ], "support": { "issues": "https://github.com/ramsey/uuid/issues", - "source": "https://github.com/ramsey/uuid/tree/4.9.0" + "source": "https://github.com/ramsey/uuid/tree/4.9.1" }, - "time": "2025-06-25T14:20:11+00:00" + "time": "2025-09-04T20:59:21+00:00" }, { "name": "react/promise", @@ -11986,16 +11986,16 @@ }, { "name": "symfony/console", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350" + "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350", - "reference": "59266a5bf6a596e3e0844fd95e6ad7ea3c1d3350", + "url": "https://api.github.com/repos/symfony/console/zipball/273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", + "reference": "273fd29ff30ba0a88ca5fb83f7cf1ab69306adae", "shasum": "" }, "require": { @@ -12060,7 +12060,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.24" + "source": "https://github.com/symfony/console/tree/v6.4.25" }, "funding": [ { @@ -12080,7 +12080,7 @@ "type": "tidelift" } ], - "time": "2025-07-30T10:38:54+00:00" + "time": "2025-08-22T10:21:53+00:00" }, { "name": "symfony/css-selector", @@ -12295,16 +12295,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.3.0", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", - "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b7dc69e71de420ac04bc9ab830cf3ffebba48191", + "reference": "b7dc69e71de420ac04bc9ab830cf3ffebba48191", "shasum": "" }, "require": { @@ -12355,7 +12355,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.3" }, "funding": [ { @@ -12366,12 +12366,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2025-04-22T09:11:45+00:00" + "time": "2025-08-13T11:49:31+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -12589,16 +12593,16 @@ }, { "name": "symfony/http-client", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "6d78fe8abecd547c159b8a49f7c88610630b7da2" + "reference": "b8e9dce2d8acba3c32af467bb58e0c3656886181" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/6d78fe8abecd547c159b8a49f7c88610630b7da2", - "reference": "6d78fe8abecd547c159b8a49f7c88610630b7da2", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b8e9dce2d8acba3c32af467bb58e0c3656886181", + "reference": "b8e9dce2d8acba3c32af467bb58e0c3656886181", "shasum": "" }, "require": { @@ -12606,6 +12610,7 @@ "psr/log": "^1|^2|^3", "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", "symfony/service-contracts": "^2.5|^3" }, "conflict": { @@ -12662,7 +12667,7 @@ "http" ], "support": { - "source": "https://github.com/symfony/http-client/tree/v6.4.24" + "source": "https://github.com/symfony/http-client/tree/v6.4.25" }, "funding": [ { @@ -12682,7 +12687,7 @@ "type": "tidelift" } ], - "time": "2025-07-14T16:38:25+00:00" + "time": "2025-08-27T07:01:16+00:00" }, { "name": "symfony/http-client-contracts", @@ -12764,16 +12769,16 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "0341e41d8d8830c31a1dff5cbc5bdb3ec872a073" + "reference": "6bc974c0035b643aa497c58d46d9e25185e4b272" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/0341e41d8d8830c31a1dff5cbc5bdb3ec872a073", - "reference": "0341e41d8d8830c31a1dff5cbc5bdb3ec872a073", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6bc974c0035b643aa497c58d46d9e25185e4b272", + "reference": "6bc974c0035b643aa497c58d46d9e25185e4b272", "shasum": "" }, "require": { @@ -12821,7 +12826,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.24" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.25" }, "funding": [ { @@ -12841,20 +12846,20 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-08-20T06:48:20+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726" + "reference": "a0ee3cea5cabf4ed960fd2ef57668ceeacdb6e15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726", - "reference": "b81dcdbe34b8e8f7b3fc7b2a47fa065d5bf30726", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a0ee3cea5cabf4ed960fd2ef57668ceeacdb6e15", + "reference": "a0ee3cea5cabf4ed960fd2ef57668ceeacdb6e15", "shasum": "" }, "require": { @@ -12939,7 +12944,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.24" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.25" }, "funding": [ { @@ -12959,20 +12964,20 @@ "type": "tidelift" } ], - "time": "2025-07-31T09:23:30+00:00" + "time": "2025-08-29T07:55:45+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "b4d7fa2c69641109979ed06e98a588d245362062" + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/b4d7fa2c69641109979ed06e98a588d245362062", - "reference": "b4d7fa2c69641109979ed06e98a588d245362062", + "url": "https://api.github.com/repos/symfony/mailer/zipball/628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2", "shasum": "" }, "require": { @@ -13023,7 +13028,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.24" + "source": "https://github.com/symfony/mailer/tree/v6.4.25" }, "funding": [ { @@ -13043,7 +13048,7 @@ "type": "tidelift" } ], - "time": "2025-07-24T08:25:04+00:00" + "time": "2025-08-13T09:41:44+00:00" }, { "name": "symfony/mime", @@ -13136,16 +13141,16 @@ }, { "name": "symfony/options-resolver", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37" + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37", - "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/0ff2f5c3df08a395232bbc3c2eb7e84912df911d", + "reference": "0ff2f5c3df08a395232bbc3c2eb7e84912df911d", "shasum": "" }, "require": { @@ -13183,7 +13188,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.3.2" + "source": "https://github.com/symfony/options-resolver/tree/v7.3.3" }, "funding": [ { @@ -13203,7 +13208,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T11:36:08+00:00" + "time": "2025-08-05T10:16:07+00:00" }, { "name": "symfony/polyfill-ctype", @@ -13871,6 +13876,86 @@ ], "time": "2025-07-08T02:45:35+00:00" }, + { + "name": "symfony/polyfill-php84", + "version": "v1.33.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/d8ced4d875142b6a7426000426b8abc631d6b191", + "reference": "d8ced4d875142b6a7426000426b8abc631d6b191", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php84\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php84/tree/v1.33.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-06-24T13:30:11+00:00" + }, { "name": "symfony/polyfill-uuid", "version": "v1.33.0", @@ -13956,16 +14041,16 @@ }, { "name": "symfony/process", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8eb6dc555bfb49b2703438d5de65cc9f138ff50b" + "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8eb6dc555bfb49b2703438d5de65cc9f138ff50b", - "reference": "8eb6dc555bfb49b2703438d5de65cc9f138ff50b", + "url": "https://api.github.com/repos/symfony/process/zipball/6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", + "reference": "6be2f0c9ab3428587c07bed03aa9e3d1b823c6c8", "shasum": "" }, "require": { @@ -13997,7 +14082,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.24" + "source": "https://github.com/symfony/process/tree/v6.4.25" }, "funding": [ { @@ -14017,7 +14102,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-08-14T06:23:17+00:00" }, { "name": "symfony/routing", @@ -14108,22 +14193,23 @@ }, { "name": "symfony/serializer", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "0ed011583fd24899fa003abf77c45d4a901714da" + "reference": "5608b04d8daaf29432d76ecc618b0fac169c2dfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/0ed011583fd24899fa003abf77c45d4a901714da", - "reference": "0ed011583fd24899fa003abf77c45d4a901714da", + "url": "https://api.github.com/repos/symfony/serializer/zipball/5608b04d8daaf29432d76ecc618b0fac169c2dfb", + "reference": "5608b04d8daaf29432d76ecc618b0fac169c2dfb", "shasum": "" }, "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php84": "^1.30" }, "conflict": { "phpdocumentor/reflection-docblock": "<3.2.2", @@ -14186,7 +14272,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.3.2" + "source": "https://github.com/symfony/serializer/tree/v7.3.3" }, "funding": [ { @@ -14206,7 +14292,7 @@ "type": "tidelift" } ], - "time": "2025-07-26T13:07:17+00:00" + "time": "2025-08-27T11:34:33+00:00" }, { "name": "symfony/service-contracts", @@ -14293,16 +14379,16 @@ }, { "name": "symfony/string", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", - "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", + "url": "https://api.github.com/repos/symfony/string/zipball/17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", + "reference": "17a426cce5fd1f0901fefa9b2a490d0038fd3c9c", "shasum": "" }, "require": { @@ -14360,7 +14446,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.3.2" + "source": "https://github.com/symfony/string/tree/v7.3.3" }, "funding": [ { @@ -14380,7 +14466,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-25T06:35:40+00:00" }, { "name": "symfony/translation", @@ -14639,16 +14725,16 @@ }, { "name": "symfony/validator", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "e5cc60fd44aab8e1d662fc0d954da322c2e08b43" + "reference": "a2f26d7c122393db75a2d41435ad8251250f8bc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/e5cc60fd44aab8e1d662fc0d954da322c2e08b43", - "reference": "e5cc60fd44aab8e1d662fc0d954da322c2e08b43", + "url": "https://api.github.com/repos/symfony/validator/zipball/a2f26d7c122393db75a2d41435ad8251250f8bc6", + "reference": "a2f26d7c122393db75a2d41435ad8251250f8bc6", "shasum": "" }, "require": { @@ -14717,7 +14803,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/validator/tree/v7.3.2" + "source": "https://github.com/symfony/validator/tree/v7.3.3" }, "funding": [ { @@ -14737,20 +14823,20 @@ "type": "tidelift" } ], - "time": "2025-07-29T20:02:46+00:00" + "time": "2025-08-27T11:34:33+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.24", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "aa29484ce0544bd69fa9f0df902e5ed7b7fe5034" + "reference": "c6cd92486e9fc32506370822c57bc02353a5a92c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/aa29484ce0544bd69fa9f0df902e5ed7b7fe5034", - "reference": "aa29484ce0544bd69fa9f0df902e5ed7b7fe5034", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c6cd92486e9fc32506370822c57bc02353a5a92c", + "reference": "c6cd92486e9fc32506370822c57bc02353a5a92c", "shasum": "" }, "require": { @@ -14805,7 +14891,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.24" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.25" }, "funding": [ { @@ -14825,20 +14911,20 @@ "type": "tidelift" } ], - "time": "2025-07-29T18:40:01+00:00" + "time": "2025-08-13T09:41:44+00:00" }, { "name": "symfony/var-exporter", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "05b3e90654c097817325d6abd284f7938b05f467" + "reference": "d4dfcd2a822cbedd7612eb6fbd260e46f87b7137" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/05b3e90654c097817325d6abd284f7938b05f467", - "reference": "05b3e90654c097817325d6abd284f7938b05f467", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/d4dfcd2a822cbedd7612eb6fbd260e46f87b7137", + "reference": "d4dfcd2a822cbedd7612eb6fbd260e46f87b7137", "shasum": "" }, "require": { @@ -14886,7 +14972,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.3.2" + "source": "https://github.com/symfony/var-exporter/tree/v7.3.3" }, "funding": [ { @@ -14906,20 +14992,20 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-18T13:10:53+00:00" }, { "name": "symfony/yaml", - "version": "v7.3.2", + "version": "v7.3.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30" + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/b8d7d868da9eb0919e99c8830431ea087d6aae30", - "reference": "b8d7d868da9eb0919e99c8830431ea087d6aae30", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d4f4a66866fe2451f61296924767280ab5732d9d", + "reference": "d4f4a66866fe2451f61296924767280ab5732d9d", "shasum": "" }, "require": { @@ -14962,7 +15048,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.3.2" + "source": "https://github.com/symfony/yaml/tree/v7.3.3" }, "funding": [ { @@ -14982,7 +15068,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-08-27T11:34:33+00:00" }, { "name": "theafolayan/listmonk-laravel", @@ -15091,6 +15177,77 @@ }, "time": "2024-12-21T16:25:41+00:00" }, + { + "name": "typesense/typesense-php", + "version": "v5.1.0", + "source": { + "type": "git", + "url": "https://github.com/typesense/typesense-php.git", + "reference": "0e8dee542c05b201becf4734319075e6c4d540b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/typesense/typesense-php/zipball/0e8dee542c05b201becf4734319075e6c4d540b3", + "reference": "0e8dee542c05b201becf4734319075e6c4d540b3", + "shasum": "" + }, + "require": { + "ext-json": "*", + "monolog/monolog": "^2.1 || ^3.0 || ^3.3", + "nyholm/psr7": "^1.3", + "php": ">=7.4", + "php-http/client-common": "^1.0 || ^2.3", + "php-http/discovery": "^1.0", + "php-http/httplug": "^1.0 || ^2.2", + "psr/http-client-implementation": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "mockery/mockery": "^1.6", + "phpunit/phpunit": "^11.2", + "squizlabs/php_codesniffer": "3.*", + "symfony/http-client": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Typesense\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Typesense", + "email": "contact@typesense.org", + "homepage": "https://typesense.org", + "role": "Developer" + }, + { + "name": "Abdullah Al-Faqeir", + "email": "abdullah@devloops.net", + "homepage": "https://www.devloops.net", + "role": "Developer" + } + ], + "description": "PHP client for Typesense Search Server: https://github.com/typesense/typesense", + "homepage": "https://github.com/typesense/typesense-php", + "support": { + "docs": "https://typesense.org/api", + "issues": "https://github.com/typesense/typesense-php/issues", + "source": "https://github.com/typesense/typesense-php" + }, + "funding": [ + { + "url": "https://github.com/typesense", + "type": "github" + } + ], + "time": "2025-05-05T17:35:26+00:00" + }, { "name": "umpirsky/country-list", "version": "2.0.6", @@ -16895,16 +17052,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "2.2.0", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8" + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/b9e61a61e39e02dd90944e9115241c7f7e76bfd8", - "reference": "b9e61a61e39e02dd90944e9115241c7f7e76bfd8", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/1e0cd5370df5dd2e556a36b9c62f62e555870495", + "reference": "1e0cd5370df5dd2e556a36b9c62f62e555870495", "shasum": "" }, "require": { @@ -16936,9 +17093,9 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/2.2.0" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.3.0" }, - "time": "2025-07-13T07:04:09+00:00" + "time": "2025-08-30T15:50:23+00:00" }, { "name": "phpunit/php-code-coverage",