From da7ec0c20ef303c5a45b9803e42ef3865272c466 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Fri, 1 Nov 2024 13:15:27 +0200 Subject: [PATCH 01/38] preview implementation of the Laminas ecosystem RFC Signed-off-by: Jurj-Bogdan --- .platform.app.yaml | 11 +- ADD_ECOSYSTEM_PACKAGE.md | 51 +++ README.md | 4 + bootstrap/gulpfile.mjs | 3 +- bootstrap/js/_ecosystem.js | 84 ++++ bootstrap/scss/_custom-styles.scss | 86 ++++ composer.json | 4 +- config/autoload/global.php | 3 + config/config.php | 1 + config/routes.php | 3 + data/ecosystem/ecosystem-packages.json | 42 ++ src/Ecosystem/ConfigProvider.php | 81 ++++ .../Console/CreateEcosystemDatabase.php | 393 ++++++++++++++++++ .../Console/SeedEcosystemDatabase.php | 222 ++++++++++ .../SeedEcosystemDatabaseDelegator.php | 28 ++ .../CreateEcosystemPackageFromArrayTrait.php | 82 ++++ src/Ecosystem/EcosystemPackage.php | 31 ++ src/Ecosystem/Handler/EcosystemHandler.php | 160 +++++++ .../Handler/EcosystemHandlerFactory.php | 32 ++ src/Ecosystem/Mapper/MapperFactory.php | 31 ++ src/Ecosystem/Mapper/MapperInterface.php | 28 ++ src/Ecosystem/Mapper/PdoMapper.php | 128 ++++++ src/Ecosystem/Mapper/PdoPaginator.php | 64 +++ src/Ecosystem/templates/list.phtml | 117 ++++++ templates/partials/footer.phtml | 1 + templates/partials/pagination.phtml | 52 +-- 26 files changed, 1713 insertions(+), 29 deletions(-) create mode 100644 ADD_ECOSYSTEM_PACKAGE.md create mode 100644 bootstrap/js/_ecosystem.js create mode 100644 data/ecosystem/ecosystem-packages.json create mode 100644 src/Ecosystem/ConfigProvider.php create mode 100644 src/Ecosystem/Console/CreateEcosystemDatabase.php create mode 100644 src/Ecosystem/Console/SeedEcosystemDatabase.php create mode 100644 src/Ecosystem/Console/SeedEcosystemDatabaseDelegator.php create mode 100644 src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php create mode 100644 src/Ecosystem/EcosystemPackage.php create mode 100644 src/Ecosystem/Handler/EcosystemHandler.php create mode 100644 src/Ecosystem/Handler/EcosystemHandlerFactory.php create mode 100644 src/Ecosystem/Mapper/MapperFactory.php create mode 100644 src/Ecosystem/Mapper/MapperInterface.php create mode 100644 src/Ecosystem/Mapper/PdoMapper.php create mode 100644 src/Ecosystem/Mapper/PdoPaginator.php create mode 100644 src/Ecosystem/templates/list.phtml diff --git a/.platform.app.yaml b/.platform.app.yaml index 6a2aef55..4c842a24 100644 --- a/.platform.app.yaml +++ b/.platform.app.yaml @@ -49,6 +49,7 @@ hooks: echo "- Installing application dependencies" composer install --no-ansi --no-dev --no-interaction --no-scripts --no-plugins --optimize-autoloader mkdir -p var/blog/feeds + mkdir -p var/ecosystem composer build deploy: | rm -f data/cache/config-cache.php @@ -79,7 +80,15 @@ crons: ./vendor/bin/laminas repository:generate-data "$PLATFORM_VARIABLES" | base64 --decode | jq '."REPO_TOKEN"' fi shutdown_timeout: 20 - + generateecosystem: + # Refresh repository data every 6 hours (UTC). + spec: '* */4 * * *' + commands: + start: | + if [ "$PLATFORM_BRANCH" = master ]; then + ./vendor/bin/laminas ecosystem:seed-db + fi + shutdown_timeout: 20 web: locations: '/': diff --git a/ADD_ECOSYSTEM_PACKAGE.md b/ADD_ECOSYSTEM_PACKAGE.md new file mode 100644 index 00000000..2e084eb4 --- /dev/null +++ b/ADD_ECOSYSTEM_PACKAGE.md @@ -0,0 +1,51 @@ +# Adding your entry to the Laminas Ecosystem + +You can add packages **available via composer** to the `data/ecosystem/ecosystem-packages.json` file by following the steps below: + +- Entries must use the [template](#new-entry-template) as a guide. +- Submit a PR. + +> Use the following command to make sure your submission will be correctly built: + +```bash +composer build +``` + +> The following command can be run individually for testing: + +```bash +./vendor/bin/laminas ecosystem:create-db +``` + +*Used for creating the database.* + +```bash +./vendor/bin/laminas ecosystem:seed-db +``` + +*Used for updating the package data every X hours.* + +## New entry template + +```json +{ + "packagistUrl": "", + "githubUrl": "", + "categories": [], + "homepage": "" +} +``` + +### New entry fields description + +- `packagistUrl` **required** + **string** - the packagist URL of the entry, with no query parameters + +- `githubUrl` + **string** - optional link to be displayed on the package card + +- `categories` + **array of strings** - user defined keywords used for filtering results + +- `homepage` + **string** - optional URL to package homepage, will overwrite "homepage" field from Packagist Api data diff --git a/README.md b/README.md index a58e03b7..9e0d37c2 100644 --- a/README.md +++ b/README.md @@ -86,3 +86,7 @@ Everyone is welcome to post a blog entry. Once submitted, it will be reviewed by If it's rejected, the reason for the rejection will be included, so you can update it and resubmit the post if applicable. The submission process is described in the [ADD_BLOG_ENTRY](ADD_BLOG_ENTRY.md) file. + +## Adding packages to the Laminas Ecosystem + +The [ADD ECOSYSTEM PACKAGE](ADD_ECOSYSTEM_PACKAGE.md) file describes the process of adding packages to the [Laminas Ecosystem](https://getlaminas.org/ecosystem) diff --git a/bootstrap/gulpfile.mjs b/bootstrap/gulpfile.mjs index f1313763..f54f42f3 100644 --- a/bootstrap/gulpfile.mjs +++ b/bootstrap/gulpfile.mjs @@ -59,7 +59,8 @@ function js() { 'node_modules/@popperjs/core/dist/umd/popper.min.js', 'node_modules/bootstrap/dist/js/bootstrap.min.js', 'node_modules/anchor-js/anchor.min.js', - 'js/base.js' + 'js/base.js', + 'js/_ecosystem.js' ])) .pipe(concat({path: 'laminas.js'})) .pipe(terser({mangle: false}).on('error', function (e) { diff --git a/bootstrap/js/_ecosystem.js b/bootstrap/js/_ecosystem.js new file mode 100644 index 00000000..ca2f8c46 --- /dev/null +++ b/bootstrap/js/_ecosystem.js @@ -0,0 +1,84 @@ +'use strict'; + +$(document).ready(function () { + $('.package-button').click(function (e) { + e.preventDefault(); + + const url = new URL(window.location.href); + const params = new URLSearchParams(url.search); + const entry = $(this).data('value'); + + if ($(this).hasClass('tag')) { + if (! params.has("tags[]", entry)) { + params.append("tags[]", entry); + url.search = params.toString(); + + window.location.replace(url.toString()); + } + } + + if ($(this).hasClass('category')) { + if (! params.has("categories[]", entry)) { + params.append("categories[]", entry); + url.search = params.toString(); + + window.location.replace(url.toString()); + } + } + }); + + $('.ecosystem-filter').click(function (e) { + e.preventDefault(); + + const url = new URL(window.location.href); + const params = new URLSearchParams(url.search); + const entry = $(this).data('value'); + + if ($(this).hasClass('tag')) { + if (params.has("tags[]", entry)) { + params.delete("tags[]", entry); + url.search = params.toString(); + + window.location.replace(url.toString()); + } + } + + if ($(this).hasClass('category')) { + if (params.has("categories[]", entry)) { + params.delete("categories[]", entry); + url.search = params.toString(); + + window.location.replace(url.toString()); + } + } + }); + + [...$('#ecosystem-pagination a')].forEach(a => { + const url = new URL(a.href) + for (let [k,v] of new URLSearchParams(window.location.search).entries()) { + if (k === 'tags[]' || k === 'categories[]' || k === 'q') { + url.searchParams.set(k,v) + } + } + a.href = url.toString(); + }) + + $('#ecosystem-search').keypress(function (e) { + const search = $(this).val(); + if (e.which === 13) { + setSearchQuery(search); + } + }); + + $('#ecosystem-search-btn').click(function (e) { + const search = $('#ecosystem-search').val(); + setSearchQuery(search); + }); + + function setSearchQuery(search) { + const url = new URL(window.location.href); + + url.searchParams.set('q', search); + window.location.replace(url.toString()); + } +}); diff --git a/bootstrap/scss/_custom-styles.scss b/bootstrap/scss/_custom-styles.scss index 7a2f4a52..4013f200 100644 --- a/bootstrap/scss/_custom-styles.scss +++ b/bootstrap/scss/_custom-styles.scss @@ -374,3 +374,89 @@ article { } } } + +#ecosystem-section { + .tag { + --filter-button-color: #00131e; + } + .category { + --filter-button-color: #678799; + } + #ecosystem-pagination { + margin-top: 1em; + } +} + +.ecosystem-container { + display: flex; + flex-direction: column; + gap: 1em; +} + +.ecosystem-package { + display: flex; + gap: 1em; + + border: 1px solid grey; + border-radius: 5px; + + padding: 1em; + + .package-name { + font-size: 1.5em; + font-weight: bold; + } + + .ecosystem-package-details { + display: flex; + flex-direction: column; + flex: 3; + } + .ecosystem-package-statistics { + flex: 1; + border-left: 1px solid grey; + padding-left: 1em; + } + .statistics-item { + margin-bottom: .5em; + } +} + +.package-categories-container, .package-tags-container { + display: flex; + flex-wrap: wrap; + gap: .5em; + margin-bottom: .5em; + + .package-button { + border: 2px solid var(--filter-button-color); + border-radius: 5px; + padding: 0 .5em; + color: var(--filter-button-color); + font-weight: bold; + background-color: white; + } +} + +#ecosystem-filter-container { + display: flex; + flex-direction: row; + gap: .5em; + + .ecosystem-filter { + border-radius: 5px; + color: white; + background-color: var(--filter-button-color); + padding: 0 .5em; + } +} + +#ecosystem-search-container { + display: flex; + margin: .5em 0; + max-width: 50%; + + #ecosystem-search-btn { + color: #00131e + } +} diff --git a/composer.json b/composer.json index 33cd4ea8..3eb90944 100644 --- a/composer.json +++ b/composer.json @@ -76,6 +76,7 @@ "psr-4": { "App\\": "src/App/", "GetLaminas\\Blog\\": "src/Blog/", + "GetLaminas\\Ecosystem\\": "src/Ecosystem/", "GetLaminas\\ReleaseFeed\\": "src/ReleaseFeed/", "GetLaminas\\Security\\": "src/Security/" } @@ -87,7 +88,8 @@ "scripts": { "build": [ "@build-blog", - "laminas security:build" + "laminas security:build", + "laminas ecosystem:create-db" ], "build-blog": [ "laminas blog:seed-db", diff --git a/config/autoload/global.php b/config/autoload/global.php index 28046348..d60678d4 100644 --- a/config/autoload/global.php +++ b/config/autoload/global.php @@ -9,4 +9,7 @@ 'blog' => [ 'db' => 'sqlite:' . realpath(getcwd()) . '/var/blog/posts.db', ], + 'packages' => [ + 'db' => 'sqlite:' . realpath(getcwd()) . '/var/ecosystem/packages.db', + ], ]; diff --git a/config/config.php b/config/config.php index 25867b7e..e0d5db9d 100644 --- a/config/config.php +++ b/config/config.php @@ -36,6 +36,7 @@ class_exists(\Mezzio\Swoole\ConfigProvider::class) // Default App module config GetLaminas\Blog\ConfigProvider::class, + GetLaminas\Ecosystem\ConfigProvider::class, GetLaminas\ReleaseFeed\ConfigProvider::class, GetLaminas\Security\ConfigProvider::class, App\ConfigProvider::class, diff --git a/config/routes.php b/config/routes.php index aac006f1..5747e65b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -41,6 +41,9 @@ // Blog routes (new GetLaminas\Blog\ConfigProvider())->registerRoutes($app, '/blog'); + // Laminas ecosystem routes + (new GetLaminas\Ecosystem\ConfigProvider())->registerRoutes($app); + // Security advisory routes (new GetLaminas\Security\ConfigProvider())->registerRoutes($app, '/security'); diff --git a/data/ecosystem/ecosystem-packages.json b/data/ecosystem/ecosystem-packages.json new file mode 100644 index 00000000..87e82c2f --- /dev/null +++ b/data/ecosystem/ecosystem-packages.json @@ -0,0 +1,42 @@ +[ + { + "packagistUrl": "https://packagist.org/packages/akrabat/ip-address-middleware", + "githubUrl": "https://github.com/akrabat/ip-address-middleware", + "categories": ["ip", "address", "middleware"], + "homepage": "" + }, + { + "packagistUrl": "https://packagist.org/packages/netglue/laminas-messenger", + "githubUrl": "https://github.com/netglue/laminas-messenger", + "categories": ["laminas", "messenger"], + "homepage": "" + }, + { + "packagistUrl": "https://packagist.org/packages/dotkernel/dot-errorhandler", + "githubUrl": "https://github.com/dotkernel/dot-errorhandler", + "categories": ["error-handling"], + "homepage": "https://dotkernel.com" + }, + { + "packagistUrl": "https://packagist.org/packages/roave/psr-container-doctrine", + "githubUrl": "", + "categories": ["middleware", "doctrine"], + "homepage": "" + }, + { + "packagistUrl": "https://packagist.org/packages/asgrim/mini-mezzio", + "githubUrl": "https://github.com/asgrim/mini-mezzio", + "categories": ["mezzio"], + "homepage": "" + }, + { + "packagistUrl": "https://packagist.org/packages/phly/phly-simple-page", + "categories": [], + "homepage": "https://github.com/phly/PhlySimplePage" + }, + { + "packagistUrl": "https://packagist.org/packages/mezzio/mezzio-aurarouter", + "categories": [], + "homepage": "" + } +] diff --git a/src/Ecosystem/ConfigProvider.php b/src/Ecosystem/ConfigProvider.php new file mode 100644 index 00000000..15fe5ad5 --- /dev/null +++ b/src/Ecosystem/ConfigProvider.php @@ -0,0 +1,81 @@ + $this->getConfig(), + 'dependencies' => $this->getDependencies(), + 'laminas-cli' => $this->getConsoleConfig(), + 'templates' => $this->getTemplateConfig(), + ]; + } + + public function getConfig(): array + { + return [ + 'db' => null, + ]; + } + + public function getDependencies(): array + { + return [ + 'factories' => [ + 'config-packages' => ConfigFactory::class, + EcosystemHandler::class => EcosystemHandlerFactory::class, + PdoMapper::class => MapperFactory::class, + ], + // phpcs:enable + // @codingStandardsIgnoreEnd + 'invokables' => [ + SeedEcosystemDatabase::class => SeedEcosystemDatabase::class, + CreateEcosystemDatabase::class => CreateEcosystemDatabase::class, + ], + 'delegators' => [ + SeedEcosystemDatabase::class => [ + SeedEcosystemDatabaseDelegator::class, + ], + ], + ]; + } + + public function getTemplateConfig(): array + { + return [ + 'paths' => [ + 'ecosystem' => [__DIR__ . '/templates'], + ], + ]; + } + + public function getConsoleConfig(): array + { + return [ + 'commands' => [ + 'ecosystem:seed-db' => SeedEcosystemDatabase::class, + 'ecosystem:create-db' => CreateEcosystemDatabase::class, + ], + ]; + } + + public function registerRoutes(Application $app, string $basePath = '/ecosystem'): void + { + $app->get($basePath . '[/]', EcosystemHandler::class, 'app.ecosystem'); + } +} diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php new file mode 100644 index 00000000..fad775f3 --- /dev/null +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -0,0 +1,393 @@ +setName('ecosystem:seed-db'); + $this->setDescription('Generate and seed the "ecosystem packages" database.'); + $this->setHelp('Re-create the blog post database from the post entities.'); + + $this->addOption( + 'path', + 'p', + InputOption::VALUE_REQUIRED, + 'Base path of the application; defaults to current working directory', + realpath(getcwd()) + ); + + $this->addOption( + 'data-path', + 'd', + InputOption::VALUE_REQUIRED, + 'Path to the database file, relative to the --path.', + EcosystemHandler::ECOSYSTEM_DIRECTORY + ); + + $this->addOption( + 'data-file', + 'f', + InputOption::VALUE_REQUIRED, + 'Path to the blog posts, relative to the --path.', + EcosystemHandler::ECOSYSTEM_FILE + ); + + $this->addOption( + 'db-path', + 'b', + InputOption::VALUE_REQUIRED, + 'Path to the database file, relative to the --path.', + self::PACKAGES_DB_PATH + ); + } + + /** + * @throws Exception + */ + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $basePath = $input->getOption('path'); + assert(is_string($basePath)); + $dataPath = $input->getOption('data-path'); + assert(is_string($dataPath)); + $dataFile = $input->getOption('data-file'); + assert(is_string($dataFile)); + $dbFile = $input->getOption('db-path'); + assert(is_string($dbFile)); + + $path = sprintf( + '%s/%s/%s', + $basePath, + $dataPath, + $dataFile + ); + + $io->title('Generating ecosystem packages database'); + + $userData = file_get_contents($path); + assert(is_string($userData)); + + $userDataArray = json_decode($userData, true); + assert(is_array($userDataArray)); + + $pdo = $this->createDatabase($dbFile); + + $this->initCurl(); + + /** @var array{packagistUrl: string, githubUrl: string, categories: array, homepage: string} $userData */ + foreach ($userDataArray as $userData) { + $curlResult = $this->getPackageData($userData); + if ($curlResult === null) { + continue; + } + + $package = $this->createEcosystemPackageFromArray($curlResult); + $this->insertPackageInDatabase($package, $pdo); + } + + $io->success('Created ecosystem packages database'); + + return 0; + } + + private function createDatabase(string $path): PDO + { + if (file_exists($path)) { + $path = realpath($path); + unlink($path); + } + + if ($path[0] !== '/') { + $path = realpath(getcwd()) . '/' . $path; + } + + $pdo = new PDO('sqlite:' . $path); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + $pdo->beginTransaction(); + $pdo->exec($this->table); + foreach ($this->indices as $index) { + $pdo->exec($index); + } + $pdo->exec($this->searchTable); + $pdo->exec($this->searchTrigger); + $pdo->exec($this->searchTriggerPostUpdate); + + $pdo->commit(); + + return $pdo; + } + + private function initCurl(): void + { + $headers = [ + 'Accept: application/vnd.github+json', + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: getlaminas.org', + ]; + + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); + } + + /** + * @param array{packagistUrl: string, githubUrl: string, categories: array, homepage: string} $userData + */ + private function getPackageData(array $userData): ?array + { + $matches = []; + preg_match('/packagist.org\/packages\/((?>\w-?)+\/(?>\w-?)+)/i', $userData['packagistUrl'], $matches); + + if (! isset($matches[1])) { + return null; + } + + $packagistUrl = sprintf( + 'https://repo.packagist.org/packages/%s.json', + $matches[1] + ); + curl_setopt($this->curl, CURLOPT_URL, $packagistUrl); + $rawResult = curl_exec($this->curl); + assert(is_string($rawResult)); + + $packagistResult = json_decode($rawResult, true); + assert(is_array($packagistResult)); + + /** + * @var array{ + * name: string, + * description: string, + * time: string, + * maintainers: array, + * versions: array, + * type: string, + * repository: string, + * github_stars: int, + * github_watchers: int, + * github_forks: int, + * github_open_issues: int, + * language: string, + * abandoned: string, + * dependents: int, + * suggesters: int, + * downloads: array{total: int, monthly: int, daily: int}, + * favers: int + * } $packageData + */ + $packageData = $packagistResult['package']; + + $lastVersionData = array_values($packageData['versions'])[0]; + $timestamp = (new DateTimeImmutable())->getTimestamp(); + + return [ + 'id' => uniqid($packageData['name']), + 'name' => $packageData['name'], + 'repository' => $packageData['repository'], + 'description' => $packageData['description'], + 'created' => $timestamp, + 'updated' => $timestamp, + 'forks' => $packageData['github_forks'], + 'watchers' => $packageData['github_watchers'], + 'stars' => $packageData['github_stars'], + 'issues' => $packageData['github_open_issues'], + 'downloads' => $packageData['downloads']['total'], + 'abandoned' => (int) isset($packageData['abandoned']), + 'packagistUrl' => $userData['packagistUrl'], + 'categories' => $userData['categories'] !== [] ? $userData['categories'] : '', + 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] + : $lastVersionData['homepage'] ?? '', + 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', + 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', + ]; + } + + private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): void + { + $statement = sprintf( + $this->initial, + $pdo->quote($package->id), + $pdo->quote($package->name), + $pdo->quote($package->packagistUrl), + $pdo->quote($package->repository), + (int) $package->abandoned, + $pdo->quote($package->description), + $pdo->quote($package->license), + $package->created->getTimestamp(), + $package->updated->getTimestamp(), + ! empty($package->categories) + ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->categories)))) + : '', + ! empty($package->tags) + ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->tags)))) + : '', + $pdo->quote($package->website), + $package->downloads, + $package->stars, + $package->forks, + $package->watchers, + $package->issues + ); + + $pdo->exec($statement); + } +} diff --git a/src/Ecosystem/Console/SeedEcosystemDatabase.php b/src/Ecosystem/Console/SeedEcosystemDatabase.php new file mode 100644 index 00000000..bea3d1a3 --- /dev/null +++ b/src/Ecosystem/Console/SeedEcosystemDatabase.php @@ -0,0 +1,222 @@ +mapper = $mapper; + } + + protected function configure(): void + { + $this->setName('ecosystem:seed-db'); + $this->setDescription('Generate and seed the "ecosystem packages" database.'); + $this->setHelp('Re-create the ecosystem packages database from the package entities.'); + + $this->addOption( + 'db-path', + 'b', + InputOption::VALUE_REQUIRED, + 'Path to the database file, relative to the --path.', + CreateEcosystemDatabase::PACKAGES_DB_PATH + ); + } + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $dbFile = $input->getOption('db-path'); + assert(is_string($dbFile)); + + /** @var array{id: string, name: string, updated: int}|null $packagesDueUpdates */ + $packagesDueUpdates = $this->mapper->fetchPackagesDueUpdates( + new DateTimeImmutable(self::PACKAGE_UPDATE_TIME) + ); + if (empty($packagesDueUpdates)) { + $io->success('No packages need updates'); + + return 0; + } + + $io->title('Updating ecosystem packages database'); + + $pdo = realpath($dbFile); + assert($pdo !== false); + + $pdo = new PDO('sqlite:' . $pdo); + + $pdo->beginTransaction(); + $this->initCurl(); + + foreach ($packagesDueUpdates as $package) { + $packageData = $this->getPackageData($package); + $this->updatePackage($packageData, $pdo); + } + + $pdo->commit(); + + $io->success('Updated ecosystem packages database'); + + return 0; + } + + private function initCurl(): void + { + $headers = [ + 'Accept: application/vnd.github+json', + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: getlaminas.org', + ]; + + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); + } + + private function getPackageData(array $package): array + { + $packagistUrl = sprintf( + 'https://repo.packagist.org/packages/%s.json', + $package['name'], + ); + curl_setopt($this->curl, CURLOPT_URL, $packagistUrl); + $rawResult = curl_exec($this->curl); + assert(is_string($rawResult)); + $packagistResult = json_decode($rawResult, true); + assert(is_array($packagistResult)); + + /** + * @var array{ + * name: string, + * repository: string, + * abandoned: string, + * description: string, + * updated: int, + * forks: int, + * watchers: int, + * stars: int, + * issues: int, + * downloads: array{total: int, monthly: int, daily: int}, + * license: string, + * tags: array|string, + * id: string + * } $packageData + */ + $packageData = $packagistResult['package']; + $lastVersionData = array_values($packageData['versions'])[0]; + + return [ + 'name' => $packageData['name'], + 'repository' => $packageData['repository'], + 'abandoned' => (int) isset($packageData['abandoned']), + 'description' => $packageData['description'], + 'updated' => (new DateTimeImmutable())->getTimestamp(), + 'forks' => (int) $packageData['github_forks'], + 'watchers' => (int) $packageData['github_watchers'], + 'stars' => (int) $packageData['github_stars'], + 'issues' => (int) $packageData['github_open_issues'], + 'downloads' => (int) $packageData['downloads']['total'], + 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', + 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', + 'id' => $package['id'], + ]; + } + + /** + * @phpcs:ignore + * @param array{ + * name: string, + * repository: string, + * abandoned: string, + * description: string, + * updated: int, + * forks: int, + * watchers: int, + * stars: int, + * issues: int, + * downloads: array{total: int, monthly: int, daily: int}, + * license: string, + * tags: array|string, + * id: string + * } $packageData + */ + private function updatePackage(array $packageData, PDO $pdo): void + { + $statement = sprintf( + $this->update, + $pdo->quote($packageData['name']), + $pdo->quote($packageData['repository']), + $packageData['abandoned'], + $pdo->quote($packageData['description']), + $pdo->quote($packageData['license']), + $packageData['updated'], + ! empty($packageData['tags']) + ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $packageData['tags'])))) + : $pdo->quote(''), + $packageData['downloads'], + $packageData['stars'], + $packageData['forks'], + $packageData['watchers'], + $packageData['issues'], + $pdo->quote($packageData['id']) + ); + + $pdo->exec($statement); + } +} diff --git a/src/Ecosystem/Console/SeedEcosystemDatabaseDelegator.php b/src/Ecosystem/Console/SeedEcosystemDatabaseDelegator.php new file mode 100644 index 00000000..349cb26e --- /dev/null +++ b/src/Ecosystem/Console/SeedEcosystemDatabaseDelegator.php @@ -0,0 +1,28 @@ +get(PdoMapper::class); + assert($pdoMapper instanceof PdoMapper); + + $command->setMapper($pdoMapper); + return $command; + } +} diff --git a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php new file mode 100644 index 00000000..730f2f37 --- /dev/null +++ b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php @@ -0,0 +1,82 @@ +, + * website: string, + * license: string, + * tags: string|array + * } $packageData + */ + private function createEcosystemPackageFromArray(array $packageData): EcosystemPackage + { + $created = $this->createDateTimeFromString((string) $packageData['created']); + $updated = $packageData['updated'] && $packageData['updated'] !== $packageData['created'] + ? $this->createDateTimeFromString((string) $packageData['updated']) + : $created; + + return new EcosystemPackage( + $packageData['id'], + $packageData['name'], + $packageData['packagistUrl'], + $packageData['repository'], + (bool) $packageData['abandoned'], + $packageData['description'], + $packageData['license'], + $created, + $updated, + is_array($packageData['categories']) + ? $packageData['categories'] + : explode('|', trim($packageData['categories'], '|')), + is_array($packageData['tags']) + ? $packageData['tags'] + : explode('|', trim($packageData['tags'], '|')), + $packageData['website'] ?? '', + $packageData['downloads'], + $packageData['stars'], + $packageData['forks'], + $packageData['watchers'], + $packageData['issues'] + ); + } + + /** + * @throws Exception + */ + private function createDateTimeFromString(string $dateString): DateTimeImmutable + { + return is_numeric($dateString) + ? new DateTimeImmutable('@' . $dateString, new DateTimeZone('America/Chicago')) + : new DateTimeImmutable($dateString); + } +} diff --git a/src/Ecosystem/EcosystemPackage.php b/src/Ecosystem/EcosystemPackage.php new file mode 100644 index 00000000..d410134a --- /dev/null +++ b/src/Ecosystem/EcosystemPackage.php @@ -0,0 +1,31 @@ +getQueryParams(); + + $tags = $queryParams['tags'] ?? []; + assert(is_array($tags)); + $categories = $queryParams['categories'] ?? []; + assert(is_array($categories)); + $search = $queryParams['q'] ?? ''; + assert(is_string($search)); + + $packages = $this->ecosystemMapper->fetchAllByFilters( + [ + 'categories' => $categories !== [] + ? array_map( + fn (string $category) => strtolower($category), + $categories + ) : null, + 'tags' => $tags !== [] + ? array_map( + fn (string $tag) => strtolower($tag), + $tags + ) : null, + ], + $search + ); + + $path = $request->getAttribute('originalRequest', $request)->getUri()->getPath(); + assert(is_string($path)); + $page = $this->getPageFromRequest($request); + $packages->setItemCountPerPage(2); + + // If the requested page is later than the last, redirect to the last + // keep set tag, category and search queries + if (count($packages) && $page > count($packages)) { + $categoriesQuery = ''; + if (! empty($categories)) { + $categoriesQuery = '&categories[]=' . implode("&categories[]=", $categories); + } + + $tagsQuery = ''; + if (! empty($tags)) { + $tagsQuery = '&tags[]=' . implode("&tags[]=", $tags); + } + + $searchQuery = ''; + if ($search !== '') { + $searchQuery = '&q=' . $search; + } + + return new RedirectResponse( + sprintf( + '%s?page=%d%s%s%s', + $path, + count($packages), + $categoriesQuery, + $tagsQuery, + $searchQuery + ) + ); + } + + $packages->setCurrentPageNumber($page); + + return new HtmlResponse($this->renderer->render( + 'ecosystem::list', + $this->prepareView( + $packages->getItemsByPage($page), + $this->preparePagination($path, $page, $packages->getPages()), + $tags, + $categories, + $search + ), + )); + } + + private function getPageFromRequest(ServerRequestInterface $request): int + { + $page = $request->getQueryParams()['page'] ?? 1; + $page = (int) $page; + return $page < 1 ? 1 : $page; + } + + private function preparePagination(string $path, int $page, object $pagination): object + { + $pagination->base_path = $path; + $pagination->is_first = $page === $pagination->first; + $pagination->is_last = $page === $pagination->last; + + $pages = []; + for ($i = (int) $pagination->firstPageInRange; $i <= (int) $pagination->lastPageInRange; $i += 1) { + $pages[] = [ + 'base_path' => $path, + 'number' => $i, + 'current' => $page === $i, + ]; + } + $pagination->pages = $pages; + + return $pagination; + } + + /** + * @param iterable $entries + * @psalm-return array + */ + private function prepareView( + iterable $entries, + object $pagination, + array $tags, + array $categories, + string $search + ): array { + return [ + ...[ + 'ecosystemPackages' => ArrayUtils::iteratorToArray($entries, false), + 'pagination' => $pagination, + 'tags' => $tags, + 'categories' => $categories, + 'search' => $search, + ], + ]; + } +} diff --git a/src/Ecosystem/Handler/EcosystemHandlerFactory.php b/src/Ecosystem/Handler/EcosystemHandlerFactory.php new file mode 100644 index 00000000..21d64b0a --- /dev/null +++ b/src/Ecosystem/Handler/EcosystemHandlerFactory.php @@ -0,0 +1,32 @@ +get(PdoMapper::class); + assert($mapper instanceof MapperInterface); + + $renderer = $container->get(TemplateRendererInterface::class); + assert($renderer instanceof TemplateRendererInterface); + + return new EcosystemHandler($mapper, $renderer); + } +} diff --git a/src/Ecosystem/Mapper/MapperFactory.php b/src/Ecosystem/Mapper/MapperFactory.php new file mode 100644 index 00000000..4af73bc1 --- /dev/null +++ b/src/Ecosystem/Mapper/MapperFactory.php @@ -0,0 +1,31 @@ +get('config-packages') ?? []; + assert(is_array($config)); + + $pdo = new PDO($config['db'] ?? ''); + $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + + return new PdoMapper($pdo); + } +} diff --git a/src/Ecosystem/Mapper/MapperInterface.php b/src/Ecosystem/Mapper/MapperInterface.php new file mode 100644 index 00000000..57274a5a --- /dev/null +++ b/src/Ecosystem/Mapper/MapperInterface.php @@ -0,0 +1,28 @@ + */ + public function fetchAll(): Paginator; + + /** @return Paginator */ + public function fetchAllByFilters(array $filters, string $search = ''): Paginator; + + /** @return Paginator */ + public function fetchAllByTag(string $tag): Paginator; + + /** @return Paginator */ + public function fetchAllByCategory(string $category): Paginator; + + public function search(string $toMatch): ?array; + + public function fetchPackagesDueUpdates(DateTimeImmutable $updated): ?array; +} diff --git a/src/Ecosystem/Mapper/PdoMapper.php b/src/Ecosystem/Mapper/PdoMapper.php new file mode 100644 index 00000000..efc91563 --- /dev/null +++ b/src/Ecosystem/Mapper/PdoMapper.php @@ -0,0 +1,128 @@ +preparePaginator($select, $count); + } + + public function fetchAllByFilters(array $filters, string $search = ''): Paginator + { + $select = 'SELECT * FROM packages'; + $count = 'SELECT COUNT(id) FROM packages'; + + $values = []; + + /** + * @var string $filterType + * @var array|null $filterValues + */ + foreach ($filters as $filterType => $filterValues) { + if ($filterValues === null) { + continue; + } + + if (property_exists(EcosystemPackage::class, $filterType)) { + foreach ($filterValues as $filterValue) { + $where = (empty($values) ? ' WHERE ' : ' AND ') . $filterType . ' LIKE :' . $filterType; + $select .= $where; + $count .= $where; + + $values[':' . $filterType] = '%' . $filterValue . '%'; + } + } + } + + if ($search !== '') { + $select .= (empty($values) ? ' WHERE ' : ' AND ') . 'name LIKE :search'; + $count .= (empty($values) ? ' WHERE ' : ' AND ') . 'name LIKE :search'; + $values[':search'] = '%' . $search . '%'; + } + + $select .= ' ORDER BY downloads DESC LIMIT :offset, :limit'; + + return $this->preparePaginator( + $select, + $count, + $values + ); + } + + public function fetchAllByTag(string $tag): Paginator + { + $select = 'SELECT * FROM packages ' + . 'WHERE tags LIKE :tag ' + . 'ORDER BY downloads ' + . 'DESC LIMIT :offset, :limit'; + $count = 'SELECT COUNT(id) FROM packages WHERE tags LIKE :tag'; + return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $tag)]); + } + + public function fetchAllByCategory(string $category): Paginator + { + $select = 'SELECT * FROM packages ' + . 'WHERE categories LIKE :category ' + . 'ORDER BY downloads ' + . 'DESC LIMIT :offset, :limit'; + $count = 'SELECT COUNT(id) FROM packages WHERE categories LIKE :category'; + return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $category)]); + } + + public function search(string $toMatch): ?array + { + $select = $this->pdo->prepare('SELECT id, title from search_packages WHERE search MATCH :query'); + if (! $select->execute([':query' => $toMatch])) { + return null; + } + + return $select->fetchAll(); + } + + /** + * @return Paginator + * @param array $params + */ + private function preparePaginator(string $select, string $count, array $params = []): Paginator + { + $select = $this->pdo->prepare($select); + $count = $this->pdo->prepare($count); + return new Paginator(new PdoPaginator( + $select, + $count, + $params + )); + } + + public function fetchPackagesDueUpdates(DateTimeImmutable $updated): ?array + { + $select = $this->pdo->prepare('SELECT id, name, updated FROM packages WHERE updated <= :updated '); + + if (! $select->execute([':updated' => $updated->getTimestamp()])) { + return null; + } + + return $select->fetchAll(); + } +} diff --git a/src/Ecosystem/Mapper/PdoPaginator.php b/src/Ecosystem/Mapper/PdoPaginator.php new file mode 100644 index 00000000..1e35c7c7 --- /dev/null +++ b/src/Ecosystem/Mapper/PdoPaginator.php @@ -0,0 +1,64 @@ + */ +class PdoPaginator implements AdapterInterface +{ + use CreateEcosystemPackageFromArrayTrait; + + protected array $params; + + /** @param array $params */ + public function __construct( + protected PDOStatement $select, + protected PDOStatement $count, + array $params = [], + ) { + $this->params = $params; + } + + /** @inheritDoc */ + #[Override] + public function getItems($offset, $itemCountPerPage): array + { + $params = array_merge($this->params, [ + ':offset' => $offset, + ':limit' => $itemCountPerPage, + ]); + + $result = $this->select->execute($params); + + if (! $result) { + throw new RuntimeException('Failed to fetch items from database'); + } + + return array_map( + $this->CreateEcosystemPackageFromArray(...), + $this->select->fetchAll(PDO::FETCH_ASSOC) + ); + } + + #[Override] + public function count(): int + { + $result = $this->count->execute($this->params); + if (! $result) { + throw new RuntimeException('Failed to fetch count from database'); + } + return (int) $this->count->fetchColumn(); + } +} diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml new file mode 100644 index 00000000..aeb7fdc1 --- /dev/null +++ b/src/Ecosystem/templates/list.phtml @@ -0,0 +1,117 @@ + $ecosystemPackages + * @var stdClass $pagination + * @var array $tags + * @var array $categories + * @var string $search + */ + +$this->layout('layout::default', ['title' => 'Laminas Ecosystem']); +?> +
+
+
+

Laminas Ecosystem

+
+
+
+ + +
+ +
+ +

+ + + +

+ +
+
+
+ +
+ +
+
+ +

name ?>

+
+ +

description ?>

+ abandoned) : ?> +

This package has been abandoned

+ + + + tags)) : ?> +
+ tags as $tag) : + if (empty($tag)) { + continue; + } + ?> + + +
+ + + categories)) :?> +
+ categories as $category) : + if (empty($category)) { + continue; + } + ?> + + +
+ + +

Updated: updated->format('Y-m-d H:i') ?>

+
+
+ + website !== '') : ?> +

+ + + Homepage + +

+ +

downloads ?> total downloads

+

stars ?> stars

+

forks ?> forks

+

watchers ?> watchers

+

+ + issues > 0 && $package->repository) : ?> + issues ?> issues + + issues ?> issues + +

+ license) : ?> +

license ?>

+ + repository) : ?> +

+ + See on GitHub +

+ +
+
+ +
+
+ insert('partials::pagination', ['pagination' => $pagination]) ?> +
+
diff --git a/templates/partials/footer.phtml b/templates/partials/footer.phtml index b461cf93..c58514f2 100644 --- a/templates/partials/footer.phtml +++ b/templates/partials/footer.phtml @@ -26,6 +26,7 @@ declare(strict_types=1);
  • MVC MVC for enterprise applications
  • API Tools Build RESTful APIs in minutes
  • Maintenance Overview Current maintenance status of Laminas & Mezzio packages
  • +
  • Laminas ecosystem List of packages using Laminas & Mezzio components
  • diff --git a/templates/partials/pagination.phtml b/templates/partials/pagination.phtml index edd3d0e5..226456e5 100644 --- a/templates/partials/pagination.phtml +++ b/templates/partials/pagination.phtml @@ -15,33 +15,33 @@ declare(strict_types=1); */ ?> pages) > 1): ?> -
    - +
    + From 810aef09d3f384cb12668c9bb05836c0cb23fc3e Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 19 Nov 2024 10:55:24 +0200 Subject: [PATCH 02/38] listing page redesign, data refresh cron changes, db no longer regenerated per build Signed-off-by: Jurj-Bogdan --- .platform.app.yaml | 7 +- ADD_ECOSYSTEM_PACKAGE.md | 10 +- bootstrap/js/_ecosystem.js | 12 +- bootstrap/scss/_custom-styles.scss | 7 +- composer.json | 5 +- config/autoload/global.php | 6 +- data/.gitignore | 1 + data/ecosystem/ecosystem-packages.json | 47 ++++-- src/Ecosystem/ConfigProvider.php | 6 +- .../Console/CreateEcosystemDatabase.php | 144 ++++++++++++++---- .../CreateEcosystemDatabaseDelegator.php | 34 +++++ .../Console/SeedEcosystemDatabase.php | 98 ++++++++---- .../CreateEcosystemPackageFromArrayTrait.php | 59 ++++--- src/Ecosystem/EcosystemPackage.php | 10 +- src/Ecosystem/Enums/EcosystemCategoryEnum.php | 12 ++ src/Ecosystem/Handler/EcosystemHandler.php | 30 ++-- src/Ecosystem/Mapper/MapperInterface.php | 2 +- src/Ecosystem/Mapper/PdoMapper.php | 19 ++- src/Ecosystem/templates/list.phtml | 112 ++++++++------ 19 files changed, 434 insertions(+), 187 deletions(-) create mode 100644 src/Ecosystem/Console/CreateEcosystemDatabaseDelegator.php create mode 100644 src/Ecosystem/Enums/EcosystemCategoryEnum.php diff --git a/.platform.app.yaml b/.platform.app.yaml index 4c842a24..800ebef7 100644 --- a/.platform.app.yaml +++ b/.platform.app.yaml @@ -25,6 +25,9 @@ mounts: 'public/share': source: local source_path: public/share + 'data/ecosystem/database': + source: local + source_path: data/ecosystem/database hooks: build: | @@ -49,12 +52,12 @@ hooks: echo "- Installing application dependencies" composer install --no-ansi --no-dev --no-interaction --no-scripts --no-plugins --optimize-autoloader mkdir -p var/blog/feeds - mkdir -p var/ecosystem composer build deploy: | rm -f data/cache/config-cache.php if [ ! -e data/cache/releases.rss ];then cp templates/releases.rss data/cache/ ;fi ./vendor/bin/laminas repository:generate-data "$PLATFORM_VARIABLES" | base64 --decode | jq '."REPO_TOKEN"' + ./vendor/bin/laminas ecosystem:create-db crons: snapshot: @@ -82,7 +85,7 @@ crons: shutdown_timeout: 20 generateecosystem: # Refresh repository data every 6 hours (UTC). - spec: '* */4 * * *' + spec: '0 */6 * * *' commands: start: | if [ "$PLATFORM_BRANCH" = master ]; then diff --git a/ADD_ECOSYSTEM_PACKAGE.md b/ADD_ECOSYSTEM_PACKAGE.md index 2e084eb4..b4324658 100644 --- a/ADD_ECOSYSTEM_PACKAGE.md +++ b/ADD_ECOSYSTEM_PACKAGE.md @@ -31,8 +31,9 @@ composer build { "packagistUrl": "", "githubUrl": "", - "categories": [], - "homepage": "" + "keywords": [], + "homepage": "", + "category": "" } ``` @@ -44,8 +45,11 @@ composer build - `githubUrl` **string** - optional link to be displayed on the package card -- `categories` +- `keywords` **array of strings** - user defined keywords used for filtering results - `homepage` **string** - optional URL to package homepage, will overwrite "homepage" field from Packagist Api data + +- `category` + **string** - package category must be one of "skeleton", "integration", "tool" diff --git a/bootstrap/js/_ecosystem.js b/bootstrap/js/_ecosystem.js index ca2f8c46..a1dc08c1 100644 --- a/bootstrap/js/_ecosystem.js +++ b/bootstrap/js/_ecosystem.js @@ -17,9 +17,9 @@ $(document).ready(function () { } } - if ($(this).hasClass('category')) { - if (! params.has("categories[]", entry)) { - params.append("categories[]", entry); + if ($(this).hasClass('keyword')) { + if (! params.has("keywords[]", entry)) { + params.append("keywords[]", entry); url.search = params.toString(); window.location.replace(url.toString()); @@ -43,9 +43,9 @@ $(document).ready(function () { } } - if ($(this).hasClass('category')) { - if (params.has("categories[]", entry)) { - params.delete("categories[]", entry); + if ($(this).hasClass('keyword')) { + if (params.has("keywords[]", entry)) { + params.delete("keywords[]", entry); url.search = params.toString(); window.location.replace(url.toString()); diff --git a/bootstrap/scss/_custom-styles.scss b/bootstrap/scss/_custom-styles.scss index 4013f200..177f2a99 100644 --- a/bootstrap/scss/_custom-styles.scss +++ b/bootstrap/scss/_custom-styles.scss @@ -379,7 +379,7 @@ article { .tag { --filter-button-color: #00131e; } - .category { + .keyword { --filter-button-color: #678799; } #ecosystem-pagination { @@ -460,3 +460,8 @@ article { color: #00131e } } + +.package-image { + height: 5em; + aspect-ratio: 1; +} diff --git a/composer.json b/composer.json index 3eb90944..c4912e5a 100644 --- a/composer.json +++ b/composer.json @@ -35,8 +35,8 @@ }, "require": { "php": "~8.3.0", - "ext-pdo": "*", "ext-curl": "*", + "ext-pdo": "*", "dflydev/fig-cookies": "^3.1.0", "laminas/laminas-cli": "^1.10.0", "laminas/laminas-component-installer": "^3.4.0", @@ -88,8 +88,7 @@ "scripts": { "build": [ "@build-blog", - "laminas security:build", - "laminas ecosystem:create-db" + "laminas security:build" ], "build-blog": [ "laminas blog:seed-db", diff --git a/config/autoload/global.php b/config/autoload/global.php index d60678d4..0de25bd2 100644 --- a/config/autoload/global.php +++ b/config/autoload/global.php @@ -2,6 +2,8 @@ declare(strict_types=1); +use GetLaminas\Ecosystem\Console\CreateEcosystemDatabase; + return [ 'release-feed' => [ 'verification_token' => getenv('RELEASE_FEED_TOKEN'), @@ -10,6 +12,8 @@ 'db' => 'sqlite:' . realpath(getcwd()) . '/var/blog/posts.db', ], 'packages' => [ - 'db' => 'sqlite:' . realpath(getcwd()) . '/var/ecosystem/packages.db', + 'db' => 'sqlite:' . realpath( + getcwd() + ) . sprintf('/%s/%s', CreateEcosystemDatabase::PACKAGES_DB_PATH, CreateEcosystemDatabase::PACKAGES_DB_FILE), ], ]; diff --git a/data/.gitignore b/data/.gitignore index bead3384..c3e61a61 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -1 +1,2 @@ assets.json +ecosystem/database diff --git a/data/ecosystem/ecosystem-packages.json b/data/ecosystem/ecosystem-packages.json index 87e82c2f..2ec46c7a 100644 --- a/data/ecosystem/ecosystem-packages.json +++ b/data/ecosystem/ecosystem-packages.json @@ -2,41 +2,60 @@ { "packagistUrl": "https://packagist.org/packages/akrabat/ip-address-middleware", "githubUrl": "https://github.com/akrabat/ip-address-middleware", - "categories": ["ip", "address", "middleware"], - "homepage": "" + "keywords": ["ip", "address", "middleware"], + "homepage": "", + "category": "tool" }, { "packagistUrl": "https://packagist.org/packages/netglue/laminas-messenger", "githubUrl": "https://github.com/netglue/laminas-messenger", - "categories": ["laminas", "messenger"], - "homepage": "" + "keywords": ["laminas", "messenger"], + "homepage": "", + "category": "tool" }, { "packagistUrl": "https://packagist.org/packages/dotkernel/dot-errorhandler", "githubUrl": "https://github.com/dotkernel/dot-errorhandler", - "categories": ["error-handling"], - "homepage": "https://dotkernel.com" + "keywords": ["error-handling"], + "homepage": "https://dotkernel.com", + "category": "integration" }, { "packagistUrl": "https://packagist.org/packages/roave/psr-container-doctrine", "githubUrl": "", - "categories": ["middleware", "doctrine"], - "homepage": "" + "keywords": ["middleware", "doctrine"], + "homepage": "", + "category": "integration" }, { "packagistUrl": "https://packagist.org/packages/asgrim/mini-mezzio", "githubUrl": "https://github.com/asgrim/mini-mezzio", - "categories": ["mezzio"], - "homepage": "" + "keywords": ["mezzio"], + "homepage": "", + "category": "skeleton" }, { "packagistUrl": "https://packagist.org/packages/phly/phly-simple-page", - "categories": [], - "homepage": "https://github.com/phly/PhlySimplePage" + "keywords": [], + "homepage": "https://github.com/phly/PhlySimplePage", + "category": "skeleton " }, { "packagistUrl": "https://packagist.org/packages/mezzio/mezzio-aurarouter", - "categories": [], - "homepage": "" + "keywords": [], + "homepage": "", + "category": "invalid" + }, + { + "packagistUrl": "https://packagist.org/packages/dotkernel/api", + "keywords": [], + "homepage": "", + "category": "skeleton" + }, + { + "packagistUrl": "https://packagist.org/packages/dotkernel/frontend", + "keywords": [""], + "homepage": "www.dotkernel.com", + "category": "skeleton" } ] diff --git a/src/Ecosystem/ConfigProvider.php b/src/Ecosystem/ConfigProvider.php index 15fe5ad5..f8d19d31 100644 --- a/src/Ecosystem/ConfigProvider.php +++ b/src/Ecosystem/ConfigProvider.php @@ -5,6 +5,7 @@ namespace GetLaminas\Ecosystem; use GetLaminas\Ecosystem\Console\CreateEcosystemDatabase; +use GetLaminas\Ecosystem\Console\CreateEcosystemDatabaseDelegator; use GetLaminas\Ecosystem\Console\SeedEcosystemDatabase; use GetLaminas\Ecosystem\Console\SeedEcosystemDatabaseDelegator; use GetLaminas\Ecosystem\Handler\EcosystemHandler; @@ -48,7 +49,10 @@ public function getDependencies(): array CreateEcosystemDatabase::class => CreateEcosystemDatabase::class, ], 'delegators' => [ - SeedEcosystemDatabase::class => [ + CreateEcosystemDatabase::class => [ + CreateEcosystemDatabaseDelegator::class, + ], + SeedEcosystemDatabase::class => [ SeedEcosystemDatabaseDelegator::class, ], ], diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index fad775f3..634cae48 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -10,6 +10,7 @@ use GetLaminas\Ecosystem\CreateEcosystemPackageFromArrayTrait; use GetLaminas\Ecosystem\EcosystemPackage; use GetLaminas\Ecosystem\Handler\EcosystemHandler; +use GetLaminas\Ecosystem\Mapper\PdoMapper; use PDO; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -19,9 +20,11 @@ use function array_values; use function assert; +use function base64_decode; use function curl_exec; use function curl_init; use function curl_setopt; +use function explode; use function file_exists; use function file_get_contents; use function getcwd; @@ -34,10 +37,11 @@ use function sprintf; use function strtolower; use function uniqid; -use function unlink; use const CURLOPT_FOLLOWLOCATION; use const CURLOPT_HTTPHEADER; +use const CURLOPT_POST; +use const CURLOPT_POSTFIELDS; use const CURLOPT_RETURNTRANSFER; use const CURLOPT_URL; @@ -45,14 +49,18 @@ class CreateEcosystemDatabase extends Command { use CreateEcosystemPackageFromArrayTrait; - public const string PACKAGES_DB_PATH = 'var/ecosystem/packages.db'; + public const string PACKAGES_DB_PATH = 'data/ecosystem/database'; + public const string PACKAGES_DB_FILE = 'packages.db'; private CurlHandle $curl; + private CurlHandle $githubCurl; + private ?string $ghToken = null; + public PdoMapper $mapper; /** @var string[] */ private array $indices = [ 'CREATE INDEX tags ON packages ( tags )', - 'CREATE INDEX categories ON packages ( categories )', + 'CREATE INDEX keywords ON packages ( keywords )', 'CREATE INDEX package_name ON packages ( name )', ]; @@ -60,6 +68,7 @@ class CreateEcosystemDatabase extends Command SELECT %s AS id, %s AS name, + %s AS type, %s AS packagistUrl, %s AS repository, %d AS abandoned, @@ -67,20 +76,23 @@ class CreateEcosystemDatabase extends Command %s AS license, %d AS created, %d AS updated, - %s AS categories, + %s AS category, + %s AS keywords, %s AS tags, %s AS website, %d AS downloads, %d AS stars, - %d AS forks, - %d AS watchers, - %d AS issues'; + %d AS issues, + %s AS image + '; private string $item = 'UNION SELECT %s, %s, %s, %s, + %s, + %s, %d, %s, %s, @@ -89,11 +101,11 @@ class CreateEcosystemDatabase extends Command %s, %s, %s, + %s, %d, %d, %d, - %d, - %d'; + %s'; private string $searchTable = 'CREATE VIRTUAL TABLE search_packages USING FTS4( id, @@ -101,7 +113,7 @@ class CreateEcosystemDatabase extends Command updated, name, tags, - categories + keywords )'; private string $searchTrigger = 'CREATE TRIGGER after_packages_insert @@ -113,7 +125,7 @@ class CreateEcosystemDatabase extends Command updated, name, tags, - categories + keywords ) VALUES ( new.id, @@ -121,7 +133,7 @@ class CreateEcosystemDatabase extends Command new.updated, new.name, new.tags, - new.categories + new.keywords ); END '; @@ -135,7 +147,7 @@ class CreateEcosystemDatabase extends Command updated = new.updated, name = new.name, tags = new.tags, - categories = new.categories + keywords = new.keywords WHERE id = new.id; END '; @@ -143,6 +155,7 @@ class CreateEcosystemDatabase extends Command private string $table = 'CREATE TABLE "packages" ( id VARCHAR(255) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, + type VARCHAR(255) NOT NULL, packagistUrl VARCHAR(255) NOT NULL, repository VARCHAR(255) NOT NULL, abandoned TINYINT NOT NULL, @@ -150,16 +163,21 @@ class CreateEcosystemDatabase extends Command license VARCHAR(255) NOT NULL, created UNSIGNED INTEGER NOT NULL, updated UNSIGNED INTEGER NOT NULL, - categories VARCHAR(255), + category VARCHAR(255) NOT NULL, + keywords VARCHAR(255), tags VARCHAR(255), website VARCHAR(255), downloads UNSIGNED INTEGER, stars UNSIGNED INTEGER, - forks UNSIGNED INTEGER, - watchers UNSIGNED INTEGER, - issues UNSIGNED INTEGER + issues UNSIGNED INTEGER, + image VARCHAR(255) NOT NULL )'; + public function setMapper(PdoMapper $mapper): void + { + $this->mapper = $mapper; + } + protected function configure(): void { $this->setName('ecosystem:seed-db'); @@ -195,7 +213,14 @@ protected function configure(): void 'b', InputOption::VALUE_REQUIRED, 'Path to the database file, relative to the --path.', - self::PACKAGES_DB_PATH + sprintf('%s/%s', self::PACKAGES_DB_PATH, self::PACKAGES_DB_FILE) + ); + + $this->addOption( + 'github-token', + 'gt', + InputOption::VALUE_OPTIONAL, + 'GitHub access token', ); } @@ -213,16 +238,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int assert(is_string($dataFile)); $dbFile = $input->getOption('db-path'); assert(is_string($dbFile)); + $this->ghToken = $input->getOption('github-token'); + if (! $this->ghToken) { + $variables = json_decode(base64_decode($_ENV['PLATFORM_VARIABLES']), true); + assert(is_array($variables)); + assert(isset($variables['REPO_TOKEN'])); + + $this->ghToken = $variables['REPO_TOKEN']; + } + assert(is_string($this->ghToken)); $path = sprintf( - '%s/%s/%s', + '%s%s/%s', $basePath, $dataPath, $dataFile ); $io->title('Generating ecosystem packages database'); - $userData = file_get_contents($path); assert(is_string($userData)); @@ -241,6 +274,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $package = $this->createEcosystemPackageFromArray($curlResult); + if ($package === null) { + continue; + } + $this->insertPackageInDatabase($package, $pdo); } @@ -251,9 +288,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function createDatabase(string $path): PDO { - if (file_exists($path)) { + if (file_exists($path) && file_get_contents($path) !== '') { $path = realpath($path); - unlink($path); + return new PDO('sqlite:' . $path); } if ($path[0] !== '/') { @@ -288,17 +325,36 @@ private function initCurl(): void curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); + + $githubHeaders = [ + 'Accept: application/vnd.github+json', + 'Authorization: Bearer ' . $this->ghToken, + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: jurj@rospace.com', + ]; + + $this->githubCurl = curl_init(); + curl_setopt($this->githubCurl, CURLOPT_HTTPHEADER, $githubHeaders); + curl_setopt($this->githubCurl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->githubCurl, CURLOPT_RETURNTRANSFER, 1); } /** - * @param array{packagistUrl: string, githubUrl: string, categories: array, homepage: string} $userData + * @phpcs:ignore + * @param array{ + * packagistUrl: string, + * githubUrl: string, + * keywords: array, + * homepage: string, + * category: string + * } $userData */ private function getPackageData(array $userData): ?array { $matches = []; preg_match('/packagist.org\/packages\/((?>\w-?)+\/(?>\w-?)+)/i', $userData['packagistUrl'], $matches); - if (! isset($matches[1])) { + if (! isset($matches[1]) || ! empty($this->mapper->searchPackage($matches[1]))) { return null; } @@ -312,7 +368,6 @@ private function getPackageData(array $userData): ?array $packagistResult = json_decode($rawResult, true); assert(is_array($packagistResult)); - /** * @var array{ * name: string, @@ -342,31 +397,54 @@ private function getPackageData(array $userData): ?array return [ 'id' => uniqid($packageData['name']), 'name' => $packageData['name'], + 'type' => $packageData['type'], 'repository' => $packageData['repository'], 'description' => $packageData['description'], 'created' => $timestamp, 'updated' => $timestamp, - 'forks' => $packageData['github_forks'], - 'watchers' => $packageData['github_watchers'], 'stars' => $packageData['github_stars'], 'issues' => $packageData['github_open_issues'], 'downloads' => $packageData['downloads']['total'], 'abandoned' => (int) isset($packageData['abandoned']), + 'category' => $userData['category'], 'packagistUrl' => $userData['packagistUrl'], - 'categories' => $userData['categories'] !== [] ? $userData['categories'] : '', + 'keywords' => $userData['keywords'] !== [] ? $userData['keywords'] : '', 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] : $lastVersionData['homepage'] ?? '', 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', + 'image' => $this->getSocialPreview($matches[1]), ]; } + private function getSocialPreview(string $package): ?string + { + $packageId = explode('/', $package); + $graphQlUrl = 'https://api.github.com/graphql'; + $graphQlQuery = sprintf( + '{"query": "query {repository(owner: \"%s\", name: \"%s\"){openGraphImageUrl}}"}', + $packageId[0], + $packageId[1] + ); + curl_setopt($this->githubCurl, CURLOPT_URL, $graphQlUrl); + curl_setopt($this->githubCurl, CURLOPT_POST, true); + curl_setopt($this->githubCurl, CURLOPT_POSTFIELDS, $graphQlQuery); + + $rawResult = curl_exec($this->githubCurl); + assert(is_string($rawResult)); + + $githubResult = json_decode($rawResult, true); + + return $githubResult['data']['repository']['openGraphImageUrl'] ?? null; + } + private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): void { $statement = sprintf( $this->initial, $pdo->quote($package->id), $pdo->quote($package->name), + $pdo->quote($package->type), $pdo->quote($package->packagistUrl), $pdo->quote($package->repository), (int) $package->abandoned, @@ -374,8 +452,9 @@ private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): v $pdo->quote($package->license), $package->created->getTimestamp(), $package->updated->getTimestamp(), - ! empty($package->categories) - ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->categories)))) + $pdo->quote($package->category->value), + ! empty($package->keywords) + ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->keywords)))) : '', ! empty($package->tags) ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->tags)))) @@ -383,9 +462,8 @@ private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): v $pdo->quote($package->website), $package->downloads, $package->stars, - $package->forks, - $package->watchers, - $package->issues + $package->issues, + $package->image !== null ? $pdo->quote($package->image) : 0, ); $pdo->exec($statement); diff --git a/src/Ecosystem/Console/CreateEcosystemDatabaseDelegator.php b/src/Ecosystem/Console/CreateEcosystemDatabaseDelegator.php new file mode 100644 index 00000000..be03ddba --- /dev/null +++ b/src/Ecosystem/Console/CreateEcosystemDatabaseDelegator.php @@ -0,0 +1,34 @@ +get(PdoMapper::class); + assert($pdoMapper instanceof PdoMapper); + + $command->setMapper($pdoMapper); + return $command; + } +} diff --git a/src/Ecosystem/Console/SeedEcosystemDatabase.php b/src/Ecosystem/Console/SeedEcosystemDatabase.php index bea3d1a3..0de62573 100644 --- a/src/Ecosystem/Console/SeedEcosystemDatabase.php +++ b/src/Ecosystem/Console/SeedEcosystemDatabase.php @@ -6,7 +6,6 @@ use CurlHandle; use DateTimeImmutable; -use GetLaminas\Ecosystem\CreateEcosystemPackageFromArrayTrait; use GetLaminas\Ecosystem\Mapper\PdoMapper; use PDO; use Symfony\Component\Console\Command\Command; @@ -17,9 +16,11 @@ use function array_values; use function assert; +use function base64_decode; use function curl_exec; use function curl_init; use function curl_setopt; +use function explode; use function implode; use function is_array; use function is_string; @@ -30,16 +31,18 @@ use const CURLOPT_FOLLOWLOCATION; use const CURLOPT_HTTPHEADER; +use const CURLOPT_POST; +use const CURLOPT_POSTFIELDS; use const CURLOPT_RETURNTRANSFER; use const CURLOPT_URL; class SeedEcosystemDatabase extends Command { - use CreateEcosystemPackageFromArrayTrait; - public const string PACKAGE_UPDATE_TIME = '6 hours ago'; private CurlHandle $curl; + private CurlHandle $githubCurl; + private ?string $ghToken = null; public PdoMapper $mapper; private string $update = 'UPDATE packages SET @@ -52,9 +55,8 @@ class SeedEcosystemDatabase extends Command tags = %s, downloads = %d, stars = %d, - forks = %d, - watchers = %d, - issues = %d + issues = %d, + image = %s WHERE id = %s;'; public function setMapper(PdoMapper $mapper): void @@ -73,7 +75,14 @@ protected function configure(): void 'b', InputOption::VALUE_REQUIRED, 'Path to the database file, relative to the --path.', - CreateEcosystemDatabase::PACKAGES_DB_PATH + sprintf('%s/%s', CreateEcosystemDatabase::PACKAGES_DB_PATH, CreateEcosystemDatabase::PACKAGES_DB_FILE) + ); + + $this->addOption( + 'github-token', + 'gt', + InputOption::VALUE_OPTIONAL, + 'GitHub access token', ); } @@ -82,6 +91,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io = new SymfonyStyle($input, $output); $dbFile = $input->getOption('db-path'); assert(is_string($dbFile)); + $this->ghToken = $input->getOption('github-token'); + if (! $this->ghToken) { + $variables = json_decode(base64_decode($_ENV['PLATFORM_VARIABLES']), true); + assert(is_array($variables)); + assert(isset($variables['REPO_TOKEN'])); + + $this->ghToken = $variables['REPO_TOKEN']; + } + assert(is_string($this->ghToken)); /** @var array{id: string, name: string, updated: int}|null $packagesDueUpdates */ $packagesDueUpdates = $this->mapper->fetchPackagesDueUpdates( @@ -127,6 +145,18 @@ private function initCurl(): void curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); + + $githubHeaders = [ + 'Accept: application/vnd.github+json', + 'Authorization: Bearer ' . $this->ghToken, + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: getlaminas.org', + ]; + + $this->githubCurl = curl_init(); + curl_setopt($this->githubCurl, CURLOPT_HTTPHEADER, $githubHeaders); + curl_setopt($this->githubCurl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->githubCurl, CURLOPT_RETURNTRANSFER, 1); } private function getPackageData(array $package): array @@ -148,8 +178,6 @@ private function getPackageData(array $package): array * abandoned: string, * description: string, * updated: int, - * forks: int, - * watchers: int, * stars: int, * issues: int, * downloads: array{total: int, monthly: int, daily: int}, @@ -167,33 +195,52 @@ private function getPackageData(array $package): array 'abandoned' => (int) isset($packageData['abandoned']), 'description' => $packageData['description'], 'updated' => (new DateTimeImmutable())->getTimestamp(), - 'forks' => (int) $packageData['github_forks'], - 'watchers' => (int) $packageData['github_watchers'], 'stars' => (int) $packageData['github_stars'], 'issues' => (int) $packageData['github_open_issues'], 'downloads' => (int) $packageData['downloads']['total'], 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', + 'image' => $this->getSocialPreview($packageData['name']), 'id' => $package['id'], ]; } + private function getSocialPreview(string $package): ?string + { + $packageId = explode('/', $package); + $graphQlQuery = sprintf( + '{"query": "query {repository(owner: \"%s\", name: \"%s\"){openGraphImageUrl}}"}', + $packageId[0], + $packageId[1] + ); + + curl_setopt($this->githubCurl, CURLOPT_URL, 'https://api.github.com/graphql'); + curl_setopt($this->githubCurl, CURLOPT_POST, true); + curl_setopt($this->githubCurl, CURLOPT_POSTFIELDS, $graphQlQuery); + + $rawResult = curl_exec($this->githubCurl); + assert(is_string($rawResult)); + + $githubResult = json_decode($rawResult, true); + + return $githubResult['data']['repository']['openGraphImageUrl'] ?? null; + } + /** * @phpcs:ignore * @param array{ - * name: string, - * repository: string, - * abandoned: string, - * description: string, - * updated: int, - * forks: int, - * watchers: int, - * stars: int, - * issues: int, - * downloads: array{total: int, monthly: int, daily: int}, - * license: string, - * tags: array|string, - * id: string + * name: string, + * repository: string, + * abandoned: string, + * description: string, + * updated: int, + * stars: int, + * issues: int, + * downloads: array{total: int, monthly: int, daily: int}, + * license: string, + * tags: array|string, + * image: string|null + * id: string * } $packageData */ private function updatePackage(array $packageData, PDO $pdo): void @@ -211,9 +258,8 @@ private function updatePackage(array $packageData, PDO $pdo): void : $pdo->quote(''), $packageData['downloads'], $packageData['stars'], - $packageData['forks'], - $packageData['watchers'], $packageData['issues'], + $packageData['image'] !== null ? $pdo->quote($packageData['image']) : '0', $pdo->quote($packageData['id']) ); diff --git a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php index 730f2f37..d8a4c476 100644 --- a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php +++ b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php @@ -7,6 +7,7 @@ use DateTimeImmutable; use DateTimeZone; use Exception; +use GetLaminas\Ecosystem\Enums\EcosystemCategoryEnum; use function explode; use function is_array; @@ -19,35 +20,43 @@ trait CreateEcosystemPackageFromArrayTrait * @throws Exception * @phpcs:ignore * @param array{ - * id: string, - * name: string, - * repository: string, - * description: string, - * created: int, - * updated: int, - * forks: int, - * watchers: int, - * stars: int, - * issues: int, - * downloads: int, - * abandoned: int, - * packagistUrl: string, - * categories: string|array, - * website: string, - * license: string, - * tags: string|array - * } $packageData + * id: string, + * name: string, + * type: string, + * repository: string, + * description: string, + * created: int, + * updated: int, + * category: string, + * stars: int, + * issues: int, + * downloads: int, + * abandoned: int, + * packagistUrl: string, + * keywords: string|array, + * website: string, + * license: string, + * tags: string|array, + * image: string|null + * } $packageData */ - private function createEcosystemPackageFromArray(array $packageData): EcosystemPackage + private function createEcosystemPackageFromArray(array $packageData): ?EcosystemPackage { $created = $this->createDateTimeFromString((string) $packageData['created']); $updated = $packageData['updated'] && $packageData['updated'] !== $packageData['created'] ? $this->createDateTimeFromString((string) $packageData['updated']) : $created; + $category = EcosystemCategoryEnum::tryFrom(trim($packageData['category'])); + + if ($category === null) { + return null; + } + return new EcosystemPackage( $packageData['id'], $packageData['name'], + $packageData['type'], $packageData['packagistUrl'], $packageData['repository'], (bool) $packageData['abandoned'], @@ -55,18 +64,18 @@ private function createEcosystemPackageFromArray(array $packageData): EcosystemP $packageData['license'], $created, $updated, - is_array($packageData['categories']) - ? $packageData['categories'] - : explode('|', trim($packageData['categories'], '|')), + $category, + is_array($packageData['keywords']) + ? $packageData['keywords'] + : explode('|', trim($packageData['keywords'], '|')), is_array($packageData['tags']) ? $packageData['tags'] : explode('|', trim($packageData['tags'], '|')), $packageData['website'] ?? '', $packageData['downloads'], $packageData['stars'], - $packageData['forks'], - $packageData['watchers'], - $packageData['issues'] + $packageData['issues'], + $packageData['image'] ?? '0' ); } diff --git a/src/Ecosystem/EcosystemPackage.php b/src/Ecosystem/EcosystemPackage.php index d410134a..11f41b2b 100644 --- a/src/Ecosystem/EcosystemPackage.php +++ b/src/Ecosystem/EcosystemPackage.php @@ -5,12 +5,14 @@ namespace GetLaminas\Ecosystem; use DateTimeInterface; +use GetLaminas\Ecosystem\Enums\EcosystemCategoryEnum; class EcosystemPackage { public function __construct( public string $id, public string $name, + public string $type, public string $packagistUrl, public string $repository, public bool $abandoned, @@ -18,14 +20,14 @@ public function __construct( public string $license, public DateTimeInterface $created, public DateTimeInterface $updated, - public array $categories, + public EcosystemCategoryEnum $category, + public array $keywords, public array $tags, public string $website, public int $downloads, public int $stars, - public int $forks, - public int $watchers, - public int $issues + public int $issues, + public string $image, ) { } } diff --git a/src/Ecosystem/Enums/EcosystemCategoryEnum.php b/src/Ecosystem/Enums/EcosystemCategoryEnum.php new file mode 100644 index 00000000..0843fbab --- /dev/null +++ b/src/Ecosystem/Enums/EcosystemCategoryEnum.php @@ -0,0 +1,12 @@ +ecosystemMapper->fetchAllByFilters( [ - 'categories' => $categories !== [] + 'keywords' => $keywords !== [] ? array_map( - fn (string $category) => strtolower($category), - $categories + fn (string $keyword) => strtolower($keyword), + $keywords ) : null, - 'tags' => $tags !== [] + 'tags' => $tags !== [] ? array_map( fn (string $tag) => strtolower($tag), $tags @@ -64,14 +64,14 @@ public function handle(ServerRequestInterface $request): ResponseInterface $path = $request->getAttribute('originalRequest', $request)->getUri()->getPath(); assert(is_string($path)); $page = $this->getPageFromRequest($request); - $packages->setItemCountPerPage(2); + $packages->setItemCountPerPage(15); // If the requested page is later than the last, redirect to the last - // keep set tag, category and search queries + // keep set tag, keyword and search queries if (count($packages) && $page > count($packages)) { - $categoriesQuery = ''; - if (! empty($categories)) { - $categoriesQuery = '&categories[]=' . implode("&categories[]=", $categories); + $keywordsQuery = ''; + if (! empty($keywords)) { + $keywordsQuery = '&keywords[]=' . implode("&keywords[]=", $keywords); } $tagsQuery = ''; @@ -89,7 +89,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface '%s?page=%d%s%s%s', $path, count($packages), - $categoriesQuery, + $keywordsQuery, $tagsQuery, $searchQuery ) @@ -104,7 +104,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface $packages->getItemsByPage($page), $this->preparePagination($path, $page, $packages->getPages()), $tags, - $categories, + $keywords, $search ), )); @@ -144,7 +144,7 @@ private function prepareView( iterable $entries, object $pagination, array $tags, - array $categories, + array $keywords, string $search ): array { return [ @@ -152,7 +152,7 @@ private function prepareView( 'ecosystemPackages' => ArrayUtils::iteratorToArray($entries, false), 'pagination' => $pagination, 'tags' => $tags, - 'categories' => $categories, + 'keywords' => $keywords, 'search' => $search, ], ]; diff --git a/src/Ecosystem/Mapper/MapperInterface.php b/src/Ecosystem/Mapper/MapperInterface.php index 57274a5a..290d3525 100644 --- a/src/Ecosystem/Mapper/MapperInterface.php +++ b/src/Ecosystem/Mapper/MapperInterface.php @@ -20,7 +20,7 @@ public function fetchAllByFilters(array $filters, string $search = ''): Paginato public function fetchAllByTag(string $tag): Paginator; /** @return Paginator */ - public function fetchAllByCategory(string $category): Paginator; + public function fetchAllByKeyword(string $keyword): Paginator; public function search(string $toMatch): ?array; diff --git a/src/Ecosystem/Mapper/PdoMapper.php b/src/Ecosystem/Mapper/PdoMapper.php index efc91563..72cfe94a 100644 --- a/src/Ecosystem/Mapper/PdoMapper.php +++ b/src/Ecosystem/Mapper/PdoMapper.php @@ -80,14 +80,14 @@ public function fetchAllByTag(string $tag): Paginator return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $tag)]); } - public function fetchAllByCategory(string $category): Paginator + public function fetchAllByKeyword(string $keyword): Paginator { $select = 'SELECT * FROM packages ' - . 'WHERE categories LIKE :category ' + . 'WHERE keywords LIKE :keyword ' . 'ORDER BY downloads ' . 'DESC LIMIT :offset, :limit'; - $count = 'SELECT COUNT(id) FROM packages WHERE categories LIKE :category'; - return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $category)]); + $count = 'SELECT COUNT(id) FROM packages WHERE keywords LIKE :keyword'; + return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $keyword)]); } public function search(string $toMatch): ?array @@ -125,4 +125,15 @@ public function fetchPackagesDueUpdates(DateTimeImmutable $updated): ?array return $select->fetchAll(); } + + public function searchPackage(string $search): ?array + { + $select = $this->pdo->prepare('SELECT name FROM packages WHERE name = :search'); + + if (! $select->execute([':search' => $search])) { + return null; + } + + return $select->fetchAll(); + } } diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml index aeb7fdc1..d520fbdd 100644 --- a/src/Ecosystem/templates/list.phtml +++ b/src/Ecosystem/templates/list.phtml @@ -7,7 +7,7 @@ declare(strict_types=1); * @var array<\GetLaminas\Ecosystem\EcosystemPackage> $ecosystemPackages * @var stdClass $pagination * @var array $tags - * @var array $categories + * @var array $keywords * @var string $search */ @@ -29,27 +29,45 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']);

    - -

    + +

    -
    +
    -
    -
    - -

    name ?>

    -
    +
    +
    + image)) :?> + ... + +
    + + +

    description ?>

    + +
    +

    Type: type ?>

    +

    Category: category->value ?>

    +
    -

    description ?>

    abandoned) : ?> -

    This package has been abandoned

    +

    This package has been abandoned

    - tags)) : ?>
    tags as $tag) : @@ -62,53 +80,51 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']);
    - categories)) :?> + keywords)) :?>
    - categories as $category) : - if (empty($category)) { + keywords as $keyword) : + if (empty($keyword)) { continue; } ?> - +
    -

    Updated: updated->format('Y-m-d H:i') ?>

    +
    +
    +

    downloads ?> downloads

    +

    stars ?> stars

    +
    +
    + license) : ?> +

    license ?>

    + +
    + repository) : ?> +

    + + See on GitHub +

    + + website !== '') : ?> +

    + + + Homepage + +

    + +
    +
    +
    -
    - - website !== '') : ?> -

    - - - Homepage - -

    - -

    downloads ?> total downloads

    -

    stars ?> stars

    -

    forks ?> forks

    -

    watchers ?> watchers

    -

    - - issues > 0 && $package->repository) : ?> - issues ?> issues - - issues ?> issues - -

    - license) : ?> -

    license ?>

    - - repository) : ?> -

    - - See on GitHub -

    - +
    +
    From c6b579082944040b80cfdf1d184be0d02c92f541 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Mon, 25 Nov 2024 16:39:07 +0200 Subject: [PATCH 03/38] listing page design, db tweaks Signed-off-by: Jurj-Bogdan --- .platform.app.yaml | 7 + bootstrap/js/_ecosystem.js | 52 ++++-- bootstrap/scss/_custom-styles.scss | 81 +++++++-- data/ecosystem/ecosystem-packages.json | 35 ++-- .../Console/CreateEcosystemDatabase.php | 67 +++---- .../Console/SeedEcosystemDatabase.php | 18 +- .../CreateEcosystemPackageFromArrayTrait.php | 13 +- src/Ecosystem/EcosystemPackage.php | 7 +- src/Ecosystem/Enums/EcosystemTypeEnum.php | 13 ++ src/Ecosystem/Enums/EcosystemUsageEnum.php | 11 ++ src/Ecosystem/Handler/EcosystemHandler.php | 68 ++++--- src/Ecosystem/Mapper/MapperInterface.php | 3 - src/Ecosystem/Mapper/PdoMapper.php | 10 -- src/Ecosystem/templates/list.phtml | 169 +++++++++++------- 14 files changed, 349 insertions(+), 205 deletions(-) create mode 100644 src/Ecosystem/Enums/EcosystemTypeEnum.php create mode 100644 src/Ecosystem/Enums/EcosystemUsageEnum.php diff --git a/.platform.app.yaml b/.platform.app.yaml index 800ebef7..25e5d633 100644 --- a/.platform.app.yaml +++ b/.platform.app.yaml @@ -92,6 +92,13 @@ crons: ./vendor/bin/laminas ecosystem:seed-db fi shutdown_timeout: 20 + +operations: + rebuildEcosystemDatabase: + role: admin + commands: + start: ./vendor/bin/laminas ecosystem:create-db --force-rebuild + web: locations: '/': diff --git a/bootstrap/js/_ecosystem.js b/bootstrap/js/_ecosystem.js index a1dc08c1..68030176 100644 --- a/bootstrap/js/_ecosystem.js +++ b/bootstrap/js/_ecosystem.js @@ -8,19 +8,46 @@ $(document).ready(function () { const params = new URLSearchParams(url.search); const entry = $(this).data('value'); - if ($(this).hasClass('tag')) { - if (! params.has("tags[]", entry)) { - params.append("tags[]", entry); + if ($(this).hasClass('keyword')) { + if (! params.has("keywords[]", entry)) { + params.append("keywords[]", entry); url.search = params.toString(); window.location.replace(url.toString()); } } - if ($(this).hasClass('keyword')) { - if (! params.has("keywords[]", entry)) { - params.append("keywords[]", entry); - url.search = params.toString(); + if ($(this).hasClass('type')) { + if (! params.has("type", entry)) { + url.searchParams.set('type', entry); + + window.location.replace(url.toString()); + } else if (params.get("type") === entry) { + url.searchParams.delete("type"); + + window.location.replace(url.toString()); + } + } + + if ($(this).hasClass('category')) { + if (! params.has("category", entry)) { + url.searchParams.set('category', entry); + + window.location.replace(url.toString()); + } else if (params.get("category") === entry) { + url.searchParams.delete("category"); + + window.location.replace(url.toString()); + } + } + + if ($(this).hasClass('usage')) { + if (! params.has("usage", entry)) { + url.searchParams.set('usage', entry); + + window.location.replace(url.toString()); + } else if (params.get("usage") === entry) { + url.searchParams.delete("usage"); window.location.replace(url.toString()); } @@ -34,15 +61,6 @@ $(document).ready(function () { const params = new URLSearchParams(url.search); const entry = $(this).data('value'); - if ($(this).hasClass('tag')) { - if (params.has("tags[]", entry)) { - params.delete("tags[]", entry); - url.search = params.toString(); - - window.location.replace(url.toString()); - } - } - if ($(this).hasClass('keyword')) { if (params.has("keywords[]", entry)) { params.delete("keywords[]", entry); @@ -56,7 +74,7 @@ $(document).ready(function () { [...$('#ecosystem-pagination a')].forEach(a => { const url = new URL(a.href) for (let [k,v] of new URLSearchParams(window.location.search).entries()) { - if (k === 'tags[]' || k === 'categories[]' || k === 'q') { + if (k === 'keywords[]' || k === 'q' || k === 'type' || k === 'category' || k === 'usage') { url.searchParams.set(k,v) } } diff --git a/bootstrap/scss/_custom-styles.scss b/bootstrap/scss/_custom-styles.scss index 177f2a99..03ba684a 100644 --- a/bootstrap/scss/_custom-styles.scss +++ b/bootstrap/scss/_custom-styles.scss @@ -376,15 +376,67 @@ article { } #ecosystem-section { - .tag { - --filter-button-color: #00131e; - } .keyword { --filter-button-color: #678799; } #ecosystem-pagination { margin-top: 1em; } + + .card { + height: 500px; + transition: all .2s ease-in-out; + + .abandoned-package { + position: absolute; + top: 0; + padding-left: 10pt; + background: #ff9102; + width: 100%; + } + + .package-image-container { + display: grid; + align-items: center; + text-align: center; + height: 200px; + } + + .card-body { + height: 200px; + overflow: hidden; + } + + .card-footer { + .card-homepage { + float: left; + } + .card-updated { + float: right; + } + } + + .default-package-image { + font-size: 100px; + padding: 50px + } + } + + .card:hover { + transform: scale(1.05); + .package-image-container { + height: 100px; + overflow: hidden; + text-align: center; + transition: height 0.3s; + } + + .card-body { + height: 300px; + transition: height 0.3s; + overflow: scroll; + } + } } .ecosystem-container { @@ -393,6 +445,10 @@ article { gap: 1em; } +#ecosystem-navbar button { + color: #00131e +} + .ecosystem-package { display: flex; gap: 1em; @@ -422,16 +478,20 @@ article { } } -.package-categories-container, .package-tags-container { +.details-item { + margin-bottom: 0; +} + +.package-categories-container { display: flex; flex-wrap: wrap; - gap: .5em; + gap: .3em; margin-bottom: .5em; .package-button { border: 2px solid var(--filter-button-color); border-radius: 5px; - padding: 0 .5em; + padding: 0 .25em; color: var(--filter-button-color); font-weight: bold; background-color: white; @@ -455,13 +515,4 @@ article { display: flex; margin: .5em 0; max-width: 50%; - - #ecosystem-search-btn { - color: #00131e - } -} - -.package-image { - height: 5em; - aspect-ratio: 1; } diff --git a/data/ecosystem/ecosystem-packages.json b/data/ecosystem/ecosystem-packages.json index 2ec46c7a..fa430413 100644 --- a/data/ecosystem/ecosystem-packages.json +++ b/data/ecosystem/ecosystem-packages.json @@ -4,58 +4,67 @@ "githubUrl": "https://github.com/akrabat/ip-address-middleware", "keywords": ["ip", "address", "middleware"], "homepage": "", - "category": "tool" + "category": "tool", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/netglue/laminas-messenger", "githubUrl": "https://github.com/netglue/laminas-messenger", "keywords": ["laminas", "messenger"], "homepage": "", - "category": "tool" + "category": "tool", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/dotkernel/dot-errorhandler", "githubUrl": "https://github.com/dotkernel/dot-errorhandler", "keywords": ["error-handling"], "homepage": "https://dotkernel.com", - "category": "integration" + "category": "integration", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/roave/psr-container-doctrine", "githubUrl": "", "keywords": ["middleware", "doctrine"], "homepage": "", - "category": "integration" + "category": "integration", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/asgrim/mini-mezzio", "githubUrl": "https://github.com/asgrim/mini-mezzio", "keywords": ["mezzio"], "homepage": "", - "category": "skeleton" + "category": "skeleton", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/phly/phly-simple-page", - "keywords": [], + "keywords": ["mvc"], "homepage": "https://github.com/phly/PhlySimplePage", - "category": "skeleton " + "category": "tool", + "usage": "mvc" }, { "packagistUrl": "https://packagist.org/packages/mezzio/mezzio-aurarouter", - "keywords": [], + "keywords": ["middleware", "http"], "homepage": "", - "category": "invalid" + "category": "tool", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/dotkernel/api", - "keywords": [], + "keywords": ["rest", "api"], "homepage": "", - "category": "skeleton" + "category": "skeleton", + "usage": "mezzio" }, { "packagistUrl": "https://packagist.org/packages/dotkernel/frontend", - "keywords": [""], + "keywords": ["frontend-application"], "homepage": "www.dotkernel.com", - "category": "skeleton" + "category": "skeleton", + "usage": "mezzio" } ] diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 634cae48..3cd6be2e 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -18,7 +18,6 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use function array_values; use function assert; use function base64_decode; use function curl_exec; @@ -37,6 +36,7 @@ use function sprintf; use function strtolower; use function uniqid; +use function unlink; use const CURLOPT_FOLLOWLOCATION; use const CURLOPT_HTTPHEADER; @@ -54,12 +54,12 @@ class CreateEcosystemDatabase extends Command private CurlHandle $curl; private CurlHandle $githubCurl; - private ?string $ghToken = null; + private ?string $ghToken = null; + private bool $forceRebuild = false; public PdoMapper $mapper; /** @var string[] */ private array $indices = [ - 'CREATE INDEX tags ON packages ( tags )', 'CREATE INDEX keywords ON packages ( keywords )', 'CREATE INDEX package_name ON packages ( name )', ]; @@ -73,12 +73,11 @@ class CreateEcosystemDatabase extends Command %s AS repository, %d AS abandoned, %s AS description, - %s AS license, + %s AS usage, %d AS created, %d AS updated, %s AS category, %s AS keywords, - %s AS tags, %s AS website, %d AS downloads, %d AS stars, @@ -92,16 +91,15 @@ class CreateEcosystemDatabase extends Command %s, %s, %s, - %s, %d, %s, %s, + %s, %d, %d, %s, %s, %s, - %s, %d, %d, %d, @@ -112,7 +110,6 @@ class CreateEcosystemDatabase extends Command created, updated, name, - tags, keywords )'; @@ -124,7 +121,6 @@ class CreateEcosystemDatabase extends Command created, updated, name, - tags, keywords ) VALUES ( @@ -132,7 +128,6 @@ class CreateEcosystemDatabase extends Command new.created, new.updated, new.name, - new.tags, new.keywords ); END @@ -146,7 +141,6 @@ class CreateEcosystemDatabase extends Command id = new.id, updated = new.updated, name = new.name, - tags = new.tags, keywords = new.keywords WHERE id = new.id; END @@ -159,13 +153,12 @@ class CreateEcosystemDatabase extends Command packagistUrl VARCHAR(255) NOT NULL, repository VARCHAR(255) NOT NULL, abandoned TINYINT NOT NULL, - description VARCHAR(255) NOT NULL, - license VARCHAR(255) NOT NULL, + description TEXT NOT NULL, + usage VARCHAR(255) NOT NULL, created UNSIGNED INTEGER NOT NULL, updated UNSIGNED INTEGER NOT NULL, category VARCHAR(255) NOT NULL, keywords VARCHAR(255), - tags VARCHAR(255), website VARCHAR(255), downloads UNSIGNED INTEGER, stars UNSIGNED INTEGER, @@ -222,6 +215,14 @@ protected function configure(): void InputOption::VALUE_OPTIONAL, 'GitHub access token', ); + + $this->addOption( + 'force-rebuild', + 'fr', + InputOption::VALUE_OPTIONAL, + 'Regenerate database file from scratch', + $this->forceRebuild + ); } /** @@ -248,6 +249,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int } assert(is_string($this->ghToken)); + $this->forceRebuild = $input->getOption('force-rebuild') !== false; + $path = sprintf( '%s%s/%s', $basePath, @@ -289,8 +292,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int private function createDatabase(string $path): PDO { if (file_exists($path) && file_get_contents($path) !== '') { - $path = realpath($path); - return new PDO('sqlite:' . $path); + if ($this->forceRebuild) { + unlink($path); + } else { + $path = realpath($path); + return new PDO('sqlite:' . $path); + } } if ($path[0] !== '/') { @@ -330,7 +337,7 @@ private function initCurl(): void 'Accept: application/vnd.github+json', 'Authorization: Bearer ' . $this->ghToken, 'X-GitHub-Api-Version: 2022-11-28', - 'User-Agent: jurj@rospace.com', + 'User-Agent: getlaminas.org', ]; $this->githubCurl = curl_init(); @@ -346,7 +353,8 @@ private function initCurl(): void * githubUrl: string, * keywords: array, * homepage: string, - * category: string + * category: string, + * usage: string * } $userData */ private function getPackageData(array $userData): ?array @@ -354,8 +362,10 @@ private function getPackageData(array $userData): ?array $matches = []; preg_match('/packagist.org\/packages\/((?>\w-?)+\/(?>\w-?)+)/i', $userData['packagistUrl'], $matches); - if (! isset($matches[1]) || ! empty($this->mapper->searchPackage($matches[1]))) { - return null; + if (! $this->forceRebuild) { + if (! isset($matches[1]) || ! empty($this->mapper->searchPackage($matches[1]))) { + return null; + } } $packagistUrl = sprintf( @@ -390,9 +400,7 @@ private function getPackageData(array $userData): ?array * } $packageData */ $packageData = $packagistResult['package']; - - $lastVersionData = array_values($packageData['versions'])[0]; - $timestamp = (new DateTimeImmutable())->getTimestamp(); + $timestamp = (new DateTimeImmutable())->getTimestamp(); return [ 'id' => uniqid($packageData['name']), @@ -406,13 +414,11 @@ private function getPackageData(array $userData): ?array 'issues' => $packageData['github_open_issues'], 'downloads' => $packageData['downloads']['total'], 'abandoned' => (int) isset($packageData['abandoned']), + 'usage' => $userData['usage'], 'category' => $userData['category'], 'packagistUrl' => $userData['packagistUrl'], 'keywords' => $userData['keywords'] !== [] ? $userData['keywords'] : '', - 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] - : $lastVersionData['homepage'] ?? '', - 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', - 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', + 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] : '', 'image' => $this->getSocialPreview($matches[1]), ]; } @@ -444,21 +450,18 @@ private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): v $this->initial, $pdo->quote($package->id), $pdo->quote($package->name), - $pdo->quote($package->type), + $pdo->quote($package->type->value), $pdo->quote($package->packagistUrl), $pdo->quote($package->repository), (int) $package->abandoned, $pdo->quote($package->description), - $pdo->quote($package->license), + $pdo->quote($package->usage->value), $package->created->getTimestamp(), $package->updated->getTimestamp(), $pdo->quote($package->category->value), ! empty($package->keywords) ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->keywords)))) : '', - ! empty($package->tags) - ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $package->tags)))) - : '', $pdo->quote($package->website), $package->downloads, $package->stars, diff --git a/src/Ecosystem/Console/SeedEcosystemDatabase.php b/src/Ecosystem/Console/SeedEcosystemDatabase.php index 0de62573..cb5e83da 100644 --- a/src/Ecosystem/Console/SeedEcosystemDatabase.php +++ b/src/Ecosystem/Console/SeedEcosystemDatabase.php @@ -14,20 +14,17 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; -use function array_values; use function assert; use function base64_decode; use function curl_exec; use function curl_init; use function curl_setopt; use function explode; -use function implode; use function is_array; use function is_string; use function json_decode; use function realpath; use function sprintf; -use function strtolower; use const CURLOPT_FOLLOWLOCATION; use const CURLOPT_HTTPHEADER; @@ -50,9 +47,7 @@ class SeedEcosystemDatabase extends Command repository = %s, abandoned = %d, description = %s, - license = %s, updated = %d, - tags = %s, downloads = %d, stars = %d, issues = %d, @@ -181,13 +176,10 @@ private function getPackageData(array $package): array * stars: int, * issues: int, * downloads: array{total: int, monthly: int, daily: int}, - * license: string, - * tags: array|string, * id: string * } $packageData */ - $packageData = $packagistResult['package']; - $lastVersionData = array_values($packageData['versions'])[0]; + $packageData = $packagistResult['package']; return [ 'name' => $packageData['name'], @@ -198,8 +190,6 @@ private function getPackageData(array $package): array 'stars' => (int) $packageData['github_stars'], 'issues' => (int) $packageData['github_open_issues'], 'downloads' => (int) $packageData['downloads']['total'], - 'license' => ! empty($lastVersionData['license']) ? $lastVersionData['license'][0] : '', - 'tags' => ! empty($lastVersionData['keywords']) ? $lastVersionData['keywords'] : '', 'image' => $this->getSocialPreview($packageData['name']), 'id' => $package['id'], ]; @@ -237,8 +227,6 @@ private function getSocialPreview(string $package): ?string * stars: int, * issues: int, * downloads: array{total: int, monthly: int, daily: int}, - * license: string, - * tags: array|string, * image: string|null * id: string * } $packageData @@ -251,11 +239,7 @@ private function updatePackage(array $packageData, PDO $pdo): void $pdo->quote($packageData['repository']), $packageData['abandoned'], $pdo->quote($packageData['description']), - $pdo->quote($packageData['license']), $packageData['updated'], - ! empty($packageData['tags']) - ? $pdo->quote(strtolower(sprintf('|%s|', implode('|', $packageData['tags'])))) - : $pdo->quote(''), $packageData['downloads'], $packageData['stars'], $packageData['issues'], diff --git a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php index d8a4c476..eec5402d 100644 --- a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php +++ b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php @@ -8,6 +8,8 @@ use DateTimeZone; use Exception; use GetLaminas\Ecosystem\Enums\EcosystemCategoryEnum; +use GetLaminas\Ecosystem\Enums\EcosystemTypeEnum; +use GetLaminas\Ecosystem\Enums\EcosystemUsageEnum; use function explode; use function is_array; @@ -25,6 +27,7 @@ trait CreateEcosystemPackageFromArrayTrait * type: string, * repository: string, * description: string, + * usage: string, * created: int, * updated: int, * category: string, @@ -36,7 +39,6 @@ trait CreateEcosystemPackageFromArrayTrait * keywords: string|array, * website: string, * license: string, - * tags: string|array, * image: string|null * } $packageData */ @@ -48,6 +50,8 @@ private function createEcosystemPackageFromArray(array $packageData): ?Ecosystem : $created; $category = EcosystemCategoryEnum::tryFrom(trim($packageData['category'])); + $type = EcosystemTypeEnum::tryFrom(trim($packageData['type'])); + $usage = EcosystemUsageEnum::tryFrom(trim($packageData['usage'])); if ($category === null) { return null; @@ -56,21 +60,18 @@ private function createEcosystemPackageFromArray(array $packageData): ?Ecosystem return new EcosystemPackage( $packageData['id'], $packageData['name'], - $packageData['type'], + $type, $packageData['packagistUrl'], $packageData['repository'], (bool) $packageData['abandoned'], $packageData['description'], - $packageData['license'], + $usage, $created, $updated, $category, is_array($packageData['keywords']) ? $packageData['keywords'] : explode('|', trim($packageData['keywords'], '|')), - is_array($packageData['tags']) - ? $packageData['tags'] - : explode('|', trim($packageData['tags'], '|')), $packageData['website'] ?? '', $packageData['downloads'], $packageData['stars'], diff --git a/src/Ecosystem/EcosystemPackage.php b/src/Ecosystem/EcosystemPackage.php index 11f41b2b..d2ed20af 100644 --- a/src/Ecosystem/EcosystemPackage.php +++ b/src/Ecosystem/EcosystemPackage.php @@ -6,23 +6,24 @@ use DateTimeInterface; use GetLaminas\Ecosystem\Enums\EcosystemCategoryEnum; +use GetLaminas\Ecosystem\Enums\EcosystemTypeEnum; +use GetLaminas\Ecosystem\Enums\EcosystemUsageEnum; class EcosystemPackage { public function __construct( public string $id, public string $name, - public string $type, + public EcosystemTypeEnum $type, public string $packagistUrl, public string $repository, public bool $abandoned, public string $description, - public string $license, + public EcosystemUsageEnum $usage, public DateTimeInterface $created, public DateTimeInterface $updated, public EcosystemCategoryEnum $category, public array $keywords, - public array $tags, public string $website, public int $downloads, public int $stars, diff --git a/src/Ecosystem/Enums/EcosystemTypeEnum.php b/src/Ecosystem/Enums/EcosystemTypeEnum.php new file mode 100644 index 00000000..1d9a5b21 --- /dev/null +++ b/src/Ecosystem/Enums/EcosystemTypeEnum.php @@ -0,0 +1,13 @@ +getQueryParams(); - $tags = $queryParams['tags'] ?? []; - assert(is_array($tags)); $keywords = $queryParams['keywords'] ?? []; assert(is_array($keywords)); + $type = $queryParams['type'] ?? ''; + assert(is_string($type)); + $type = EcosystemTypeEnum::tryFrom($type)?->name; + $category = $queryParams['category'] ?? ''; + assert(is_string($category)); + $category = EcosystemCategoryEnum::tryFrom($category)?->name; + $usage = $queryParams['usage'] ?? ''; + assert(is_string($usage)); + $usage = EcosystemUsageEnum::tryFrom($usage)?->name; $search = $queryParams['q'] ?? ''; assert(is_string($search)); @@ -52,11 +62,9 @@ public function handle(ServerRequestInterface $request): ResponseInterface fn (string $keyword) => strtolower($keyword), $keywords ) : null, - 'tags' => $tags !== [] - ? array_map( - fn (string $tag) => strtolower($tag), - $tags - ) : null, + 'type' => [$type], + 'category' => [$category], + 'usage' => [$usage], ], $search ); @@ -67,31 +75,43 @@ public function handle(ServerRequestInterface $request): ResponseInterface $packages->setItemCountPerPage(15); // If the requested page is later than the last, redirect to the last - // keep set tag, keyword and search queries + // keep set keyword and search queries if (count($packages) && $page > count($packages)) { $keywordsQuery = ''; if (! empty($keywords)) { $keywordsQuery = '&keywords[]=' . implode("&keywords[]=", $keywords); } - $tagsQuery = ''; - if (! empty($tags)) { - $tagsQuery = '&tags[]=' . implode("&tags[]=", $tags); - } - $searchQuery = ''; if ($search !== '') { $searchQuery = '&q=' . $search; } + $typeQuery = ''; + if ($type !== '') { + $typeQuery = '&type=' . $type; + } + + $categoryQuery = ''; + if ($category !== '') { + $categoryQuery = '&category=' . $category; + } + + $usageQuery = ''; + if ($usage !== '') { + $usageQuery = '&usage=' . $usage; + } + return new RedirectResponse( sprintf( - '%s?page=%d%s%s%s', + '%s?page=%d%s%s%s%s%s', $path, count($packages), $keywordsQuery, - $tagsQuery, - $searchQuery + $searchQuery, + $typeQuery, + $categoryQuery, + $usageQuery ) ); } @@ -103,9 +123,11 @@ public function handle(ServerRequestInterface $request): ResponseInterface $this->prepareView( $packages->getItemsByPage($page), $this->preparePagination($path, $page, $packages->getPages()), - $tags, $keywords, - $search + $search, + $type, + $category, + $usage ), )); } @@ -143,17 +165,21 @@ private function preparePagination(string $path, int $page, object $pagination): private function prepareView( iterable $entries, object $pagination, - array $tags, array $keywords, - string $search + string $search, + ?string $typeQuery, + ?string $categoryQuery, + ?string $usageQuery ): array { return [ ...[ 'ecosystemPackages' => ArrayUtils::iteratorToArray($entries, false), 'pagination' => $pagination, - 'tags' => $tags, 'keywords' => $keywords, 'search' => $search, + 'type' => $typeQuery, + 'category' => $categoryQuery, + 'usage' => $usageQuery, ], ]; } diff --git a/src/Ecosystem/Mapper/MapperInterface.php b/src/Ecosystem/Mapper/MapperInterface.php index 290d3525..0b75db85 100644 --- a/src/Ecosystem/Mapper/MapperInterface.php +++ b/src/Ecosystem/Mapper/MapperInterface.php @@ -16,9 +16,6 @@ public function fetchAll(): Paginator; /** @return Paginator */ public function fetchAllByFilters(array $filters, string $search = ''): Paginator; - /** @return Paginator */ - public function fetchAllByTag(string $tag): Paginator; - /** @return Paginator */ public function fetchAllByKeyword(string $keyword): Paginator; diff --git a/src/Ecosystem/Mapper/PdoMapper.php b/src/Ecosystem/Mapper/PdoMapper.php index 72cfe94a..3e954818 100644 --- a/src/Ecosystem/Mapper/PdoMapper.php +++ b/src/Ecosystem/Mapper/PdoMapper.php @@ -70,16 +70,6 @@ public function fetchAllByFilters(array $filters, string $search = ''): Paginato ); } - public function fetchAllByTag(string $tag): Paginator - { - $select = 'SELECT * FROM packages ' - . 'WHERE tags LIKE :tag ' - . 'ORDER BY downloads ' - . 'DESC LIMIT :offset, :limit'; - $count = 'SELECT COUNT(id) FROM packages WHERE tags LIKE :tag'; - return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $tag)]); - } - public function fetchAllByKeyword(string $keyword): Paginator { $select = 'SELECT * FROM packages ' diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml index d520fbdd..dc3fc03c 100644 --- a/src/Ecosystem/templates/list.phtml +++ b/src/Ecosystem/templates/list.phtml @@ -6,80 +6,113 @@ declare(strict_types=1); * @var League\Plates\Template\Template $this * @var array<\GetLaminas\Ecosystem\EcosystemPackage> $ecosystemPackages * @var stdClass $pagination - * @var array $tags * @var array $keywords * @var string $search + * @var string $type + * @var string $category + * @var string $usage */ +use GetLaminas\Ecosystem\Enums\EcosystemCategoryEnum; +use GetLaminas\Ecosystem\Enums\EcosystemTypeEnum; +use GetLaminas\Ecosystem\Enums\EcosystemUsageEnum; + $this->layout('layout::default', ['title' => 'Laminas Ecosystem']); ?>
    -
    -
    +
    +

    Laminas Ecosystem

    -
    -
    - - -
    -
    - -

    - + + +
    + +

    +
    -
    +
    -
    +
    - image)) :?> - ... - +
    + abandoned) : ?> +

    + This package has been abandoned +

    + + image)) :?> + ... + + category === EcosystemCategoryEnum::Skeleton) : ?> + + category === EcosystemCategoryEnum::Integration) : ?> + + category === EcosystemCategoryEnum::Tool) : ?> + + + +
    - -

    description ?>

    -
    -

    Type: type ?>

    +

    Type: type->value ?>

    +

    Usage: usage->value ?>

    Category: category->value ?>

    - abandoned) : ?> -

    This package has been abandoned

    - - - tags)) : ?> -
    - tags as $tag) : - if (empty($tag)) { - continue; - } - ?> - - -
    - - keywords)) :?>
    keywords as $keyword) : @@ -94,34 +127,34 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']);
    -

    downloads ?> downloads

    -

    stars ?> stars

    -
    -
    - license) : ?> -

    license ?>

    + repository) : ?> +

    + + Source +

    -
    - repository) : ?> -

    - - See on GitHub -

    - - website !== '') : ?> -

    - - - Homepage - -

    - -
    +

    downloads ?>

    +

    stars ?>

    +

    description ?>

    From 0c5b576fbe35e3788988b39ea78e5881cd5240ae Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Mon, 25 Nov 2024 18:58:34 +0200 Subject: [PATCH 04/38] clear filters button Signed-off-by: Jurj-Bogdan --- bootstrap/js/_ecosystem.js | 12 ++++++++++++ src/Ecosystem/templates/list.phtml | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/bootstrap/js/_ecosystem.js b/bootstrap/js/_ecosystem.js index 68030176..2c619614 100644 --- a/bootstrap/js/_ecosystem.js +++ b/bootstrap/js/_ecosystem.js @@ -99,4 +99,16 @@ $(document).ready(function () { url.searchParams.set('q', search); window.location.replace(url.toString()); } + + $('#clear-filters-button').click(function (e) { + const url = new URL(window.location.href); + + for (let [k,v] of new URLSearchParams(window.location.search).entries()) { + if (k === 'type' || k === 'category' || k === 'usage') { + url.searchParams.delete(k) + } + } + + window.location.replace(url.toString()); + }); }); diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml index dc3fc03c..f17a538e 100644 --- a/src/Ecosystem/templates/list.phtml +++ b/src/Ecosystem/templates/list.phtml @@ -67,6 +67,10 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']);
    + +
    + +
    From 4719966ebefba99557d685b09d714609c8d1cf2a Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Mon, 2 Dec 2024 19:04:56 +0200 Subject: [PATCH 05/38] missing image fix, extra heading & navbar changes Signed-off-by: Jurj-Bogdan --- bootstrap/scss/_custom-styles.scss | 30 +++++- data/ecosystem/ecosystem-packages.json | 14 +++ .../Console/CreateEcosystemDatabase.php | 12 ++- src/Ecosystem/Handler/EcosystemHandler.php | 25 +++-- src/Ecosystem/templates/list.phtml | 91 +++++++++++-------- 5 files changed, 117 insertions(+), 55 deletions(-) diff --git a/bootstrap/scss/_custom-styles.scss b/bootstrap/scss/_custom-styles.scss index 03ba684a..6b7c241c 100644 --- a/bootstrap/scss/_custom-styles.scss +++ b/bootstrap/scss/_custom-styles.scss @@ -379,10 +379,16 @@ article { .keyword { --filter-button-color: #678799; } + #ecosystem-pagination { margin-top: 1em; } + a.package-button { + display: flex; + justify-content: space-between; + } + .card { height: 500px; transition: all .2s ease-in-out; @@ -502,6 +508,7 @@ article { display: flex; flex-direction: row; gap: .5em; + margin: .5em 0; .ecosystem-filter { border-radius: 5px; @@ -512,7 +519,26 @@ article { } #ecosystem-search-container { - display: flex; margin: .5em 0; - max-width: 50%; + display: flex; + flex-direction: row; + justify-content: space-between; + + input { + margin-left: 1em; + } +} + +#packageNavbarToggle { + margin-left: 1em; + justify-content: space-between; } + +#packageNavbarToggle.show, #packageNavbarToggle.collapsing { + @media(max-width:768px) { + display: flex; + flex-direction: column; + gap: .5em; + align-items: baseline; + } +} \ No newline at end of file diff --git a/data/ecosystem/ecosystem-packages.json b/data/ecosystem/ecosystem-packages.json index fa430413..c49b82bb 100644 --- a/data/ecosystem/ecosystem-packages.json +++ b/data/ecosystem/ecosystem-packages.json @@ -66,5 +66,19 @@ "homepage": "www.dotkernel.com", "category": "skeleton", "usage": "mezzio" + }, + { + "packagistUrl": "https://packagist.org/packages/lm-commons/lmc-rbac-mvc", + "keywords": ["mvc", "rbac", "permissions"], + "homepage": "", + "category": "tool", + "usage": "mvc" + }, + { + "packagistUrl": "https://packagist.org/packages/lm-commons/lmc-cors", + "keywords": ["mvc", "cors"], + "homepage": "", + "category": "tool", + "usage": "mvc" } ] diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 3cd6be2e..37352b17 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -34,6 +34,7 @@ use function preg_match; use function realpath; use function sprintf; +use function str_replace; use function strtolower; use function uniqid; use function unlink; @@ -400,7 +401,12 @@ private function getPackageData(array $userData): ?array * } $packageData */ $packageData = $packagistResult['package']; - $timestamp = (new DateTimeImmutable())->getTimestamp(); + + if (isset($packageData['abandoned'])) { + return null; + } + + $timestamp = (new DateTimeImmutable())->getTimestamp(); return [ 'id' => uniqid($packageData['name']), @@ -419,7 +425,9 @@ private function getPackageData(array $userData): ?array 'packagistUrl' => $userData['packagistUrl'], 'keywords' => $userData['keywords'] !== [] ? $userData['keywords'] : '', 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] : '', - 'image' => $this->getSocialPreview($matches[1]), + 'image' => $this->getSocialPreview( + str_replace('https://github.com/', '', $packageData['repository']) ?? $matches[1] + ), ]; } diff --git a/src/Ecosystem/Handler/EcosystemHandler.php b/src/Ecosystem/Handler/EcosystemHandler.php index 134b73b2..86bae51e 100644 --- a/src/Ecosystem/Handler/EcosystemHandler.php +++ b/src/Ecosystem/Handler/EcosystemHandler.php @@ -43,16 +43,13 @@ public function handle(ServerRequestInterface $request): ResponseInterface $keywords = $queryParams['keywords'] ?? []; assert(is_array($keywords)); - $type = $queryParams['type'] ?? ''; - assert(is_string($type)); + $type = $queryParams['type'] ?? ''; $type = EcosystemTypeEnum::tryFrom($type)?->name; $category = $queryParams['category'] ?? ''; - assert(is_string($category)); $category = EcosystemCategoryEnum::tryFrom($category)?->name; $usage = $queryParams['usage'] ?? ''; - assert(is_string($usage)); - $usage = EcosystemUsageEnum::tryFrom($usage)?->name; - $search = $queryParams['q'] ?? ''; + $usage = EcosystemUsageEnum::tryFrom($usage)?->name; + $search = $queryParams['q'] ?? ''; assert(is_string($search)); $packages = $this->ecosystemMapper->fetchAllByFilters( @@ -72,7 +69,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface $path = $request->getAttribute('originalRequest', $request)->getUri()->getPath(); assert(is_string($path)); $page = $this->getPageFromRequest($request); - $packages->setItemCountPerPage(15); + $packages->setItemCountPerPage(9); // If the requested page is later than the last, redirect to the last // keep set keyword and search queries @@ -84,22 +81,22 @@ public function handle(ServerRequestInterface $request): ResponseInterface $searchQuery = ''; if ($search !== '') { - $searchQuery = '&q=' . $search; + $searchQuery = '&q=' . strtolower($search); } $typeQuery = ''; - if ($type !== '') { - $typeQuery = '&type=' . $type; + if ($type !== null) { + $typeQuery = '&type=' . strtolower($type); } $categoryQuery = ''; - if ($category !== '') { - $categoryQuery = '&category=' . $category; + if ($category !== null) { + $categoryQuery = '&category=' . strtolower($category); } $usageQuery = ''; - if ($usage !== '') { - $usageQuery = '&usage=' . $usage; + if ($usage !== null) { + $usageQuery = '&usage=' . strtolower($usage); } return new RedirectResponse( diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml index f17a538e..c199710c 100644 --- a/src/Ecosystem/templates/list.phtml +++ b/src/Ecosystem/templates/list.phtml @@ -23,53 +23,70 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']);

    Laminas Ecosystem

    +
    Third party packages which provide explicit support for Laminas packages
    From 03253626becfb15400598fa7c888cb73ce04a848 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 10 Dec 2024 15:52:26 +0200 Subject: [PATCH 06/38] JSON validation GitHub workflow Signed-off-by: Jurj-Bogdan --- .github/workflows/validate-packages.yml | 28 +++++++++++++++++++++++++ data/ecosystem/ecosystem-packages.json | 5 ----- 2 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/validate-packages.yml diff --git a/.github/workflows/validate-packages.yml b/.github/workflows/validate-packages.yml new file mode 100644 index 00000000..dce799ff --- /dev/null +++ b/.github/workflows/validate-packages.yml @@ -0,0 +1,28 @@ +name: Validate ecosystem packages JSON file + +on: + pull_request: + push: + branches: + tags: + +jobs: + validate-packages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - run: | + packages=$(cat ./data/ecosystem/ecosystem-packages.json); + if [ ! -z "$packages" ] && [ $(echo $packages | jq empty > /dev/null 2>&1; echo $?) -eq 0 ]; then + for key in packagistUrl keywords homepage category usage; do + if ! $(echo $packages | jq ".[]" | jq "has(\"$key\")" | jq 'select(. == false)'); then + echo "Invalid JSON. Missing key \"$key\"." + exit 1; + fi + done + echo "Valid JSON." + exit 0; + else + echo "Invalid JSON." + exit 1; + fi diff --git a/data/ecosystem/ecosystem-packages.json b/data/ecosystem/ecosystem-packages.json index c49b82bb..a343c2c4 100644 --- a/data/ecosystem/ecosystem-packages.json +++ b/data/ecosystem/ecosystem-packages.json @@ -1,7 +1,6 @@ [ { "packagistUrl": "https://packagist.org/packages/akrabat/ip-address-middleware", - "githubUrl": "https://github.com/akrabat/ip-address-middleware", "keywords": ["ip", "address", "middleware"], "homepage": "", "category": "tool", @@ -9,7 +8,6 @@ }, { "packagistUrl": "https://packagist.org/packages/netglue/laminas-messenger", - "githubUrl": "https://github.com/netglue/laminas-messenger", "keywords": ["laminas", "messenger"], "homepage": "", "category": "tool", @@ -17,7 +15,6 @@ }, { "packagistUrl": "https://packagist.org/packages/dotkernel/dot-errorhandler", - "githubUrl": "https://github.com/dotkernel/dot-errorhandler", "keywords": ["error-handling"], "homepage": "https://dotkernel.com", "category": "integration", @@ -25,7 +22,6 @@ }, { "packagistUrl": "https://packagist.org/packages/roave/psr-container-doctrine", - "githubUrl": "", "keywords": ["middleware", "doctrine"], "homepage": "", "category": "integration", @@ -33,7 +29,6 @@ }, { "packagistUrl": "https://packagist.org/packages/asgrim/mini-mezzio", - "githubUrl": "https://github.com/asgrim/mini-mezzio", "keywords": ["mezzio"], "homepage": "", "category": "skeleton", From 3b467e2870c32676758fdb55016a0c4f7ca00332 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Fri, 13 Dec 2024 12:00:55 +0200 Subject: [PATCH 07/38] jquery replaced with vanilla js Signed-off-by: Jurj-Bogdan --- bootstrap/js/_ecosystem.js | 168 ++++++++++++++--------------- bootstrap/scss/_custom-styles.scss | 2 +- src/Ecosystem/templates/list.phtml | 15 ++- 3 files changed, 89 insertions(+), 96 deletions(-) diff --git a/bootstrap/js/_ecosystem.js b/bootstrap/js/_ecosystem.js index 2c619614..7e2443ef 100644 --- a/bootstrap/js/_ecosystem.js +++ b/bootstrap/js/_ecosystem.js @@ -1,114 +1,102 @@ 'use strict'; -$(document).ready(function () { - $('.package-button').click(function (e) { - e.preventDefault(); - - const url = new URL(window.location.href); - const params = new URLSearchParams(url.search); - const entry = $(this).data('value'); - - if ($(this).hasClass('keyword')) { - if (! params.has("keywords[]", entry)) { - params.append("keywords[]", entry); - url.search = params.toString(); - - window.location.replace(url.toString()); - } +document.querySelectorAll('.package-button.type, .package-button.category, .package-button.usage').forEach(button => { + button.addEventListener('click', handleFilters); +}) + +document.querySelectorAll('.package-button.keyword').forEach(button => { + button.addEventListener('click', handleKeywords); +}) + +document.querySelectorAll('.ecosystem-filter').forEach(button => { + button.addEventListener('click', removeKeyword); +}) + +document.querySelectorAll('#ecosystem-pagination a').forEach(a => { + const url = new URL(a.href) + for (let [k,v] of new URLSearchParams(window.location.search).entries()) { + if (k === 'keywords[]' || k === 'q' || k === 'type' || k === 'category' || k === 'usage') { + url.searchParams.set(k,v); } + } + a.href = url.toString(); +}) - if ($(this).hasClass('type')) { - if (! params.has("type", entry)) { - url.searchParams.set('type', entry); - - window.location.replace(url.toString()); - } else if (params.get("type") === entry) { - url.searchParams.delete("type"); +document.querySelector('#clear-filters-button')?.addEventListener('click', function () { + const url = new URL(window.location.href); - window.location.replace(url.toString()); - } + for (let [k,v] of new URLSearchParams(window.location.search).entries()) { + if (k !== 'page') { + url.searchParams.delete(k); } + } - if ($(this).hasClass('category')) { - if (! params.has("category", entry)) { - url.searchParams.set('category', entry); - - window.location.replace(url.toString()); - } else if (params.get("category") === entry) { - url.searchParams.delete("category"); - - window.location.replace(url.toString()); - } - } + window.location.replace(url.toString()); +}); - if ($(this).hasClass('usage')) { - if (! params.has("usage", entry)) { - url.searchParams.set('usage', entry); +document.querySelector('#ecosystem-search-btn').addEventListener('click', function () { + setSearchQuery(document.querySelector('#ecosystem-search').value); +}); - window.location.replace(url.toString()); - } else if (params.get("usage") === entry) { - url.searchParams.delete("usage"); +document.querySelector('#ecosystem-search').addEventListener('keypress', function (e) { + const search = this.value; + if (e.which === 13) { + setSearchQuery(search); + } +}) - window.location.replace(url.toString()); - } +function handleFilters() { + for (const filter of ['type', 'category', 'usage']) { + if (this.classList.contains(filter)) { + handleParams(filter, this.dataset.value); } - }); - - $('.ecosystem-filter').click(function (e) { - e.preventDefault(); + } +} - const url = new URL(window.location.href); - const params = new URLSearchParams(url.search); - const entry = $(this).data('value'); +function handleParams(filterKey, filterValue) { + const url = new URL(window.location.href); + const params = new URLSearchParams(url.search); - if ($(this).hasClass('keyword')) { - if (params.has("keywords[]", entry)) { - params.delete("keywords[]", entry); - url.search = params.toString(); + if (! params.has(filterKey, filterValue)) { + url.searchParams.set(filterKey, filterValue); - window.location.replace(url.toString()); - } - } - }); - - [...$('#ecosystem-pagination a')].forEach(a => { - const url = new URL(a.href) - for (let [k,v] of new URLSearchParams(window.location.search).entries()) { - if (k === 'keywords[]' || k === 'q' || k === 'type' || k === 'category' || k === 'usage') { - url.searchParams.set(k,v) - } - } - a.href = url.toString(); - }) + window.location.replace(url.toString()); + } else if (params.get(filterKey) === filterValue) { + url.searchParams.delete(filterKey); - $('#ecosystem-search').keypress(function (e) { - const search = $(this).val(); - if (e.which === 13) { - setSearchQuery(search); - } - }); + window.location.replace(url.toString()); + } +} - $('#ecosystem-search-btn').click(function (e) { - const search = $('#ecosystem-search').val(); - setSearchQuery(search); - }); +function handleKeywords() { + const url = new URL(window.location.href); + const params = new URLSearchParams(url.search); + const keyword = this.dataset.value; - function setSearchQuery(search) { - const url = new URL(window.location.href); + if (! params.has("keywords[]", keyword)) { + params.append("keywords[]", keyword); + url.search = params.toString(); - url.searchParams.set('q', search); window.location.replace(url.toString()); } +} - $('#clear-filters-button').click(function (e) { - const url = new URL(window.location.href); +function removeKeyword() { + const url = new URL(window.location.href); + const params = new URLSearchParams(url.search); + const keyword = this.dataset.value; - for (let [k,v] of new URLSearchParams(window.location.search).entries()) { - if (k === 'type' || k === 'category' || k === 'usage') { - url.searchParams.delete(k) - } - } + if (params.has("keywords[]", keyword)) { + params.delete("keywords[]", keyword); + url.search = params.toString(); window.location.replace(url.toString()); - }); -}); + } +} + +function setSearchQuery(search) { + const url = new URL(window.location.href); + + url.searchParams.set('q', search); + window.location.replace(url.toString()); +} diff --git a/bootstrap/scss/_custom-styles.scss b/bootstrap/scss/_custom-styles.scss index 6b7c241c..b02d014d 100644 --- a/bootstrap/scss/_custom-styles.scss +++ b/bootstrap/scss/_custom-styles.scss @@ -541,4 +541,4 @@ article { gap: .5em; align-items: baseline; } -} \ No newline at end of file +} diff --git a/src/Ecosystem/templates/list.phtml b/src/Ecosystem/templates/list.phtml index c199710c..c9434710 100644 --- a/src/Ecosystem/templates/list.phtml +++ b/src/Ecosystem/templates/list.phtml @@ -32,8 +32,11 @@ $this->layout('layout::default', ['title' => 'Laminas Ecosystem']); - - + +
    + + +
    From b2c58605de1f57c7aa1db542e09a85988dcfb53e Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Fri, 13 Dec 2024 12:58:40 +0200 Subject: [PATCH 08/38] package homepage fix Signed-off-by: Jurj-Bogdan --- src/Ecosystem/Console/CreateEcosystemDatabase.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 37352b17..06da725a 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -18,6 +18,7 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_key_first; use function assert; use function base64_decode; use function curl_exec; @@ -26,6 +27,7 @@ use function explode; use function file_exists; use function file_get_contents; +use function filter_var; use function getcwd; use function implode; use function is_array; @@ -45,6 +47,7 @@ use const CURLOPT_POSTFIELDS; use const CURLOPT_RETURNTRANSFER; use const CURLOPT_URL; +use const FILTER_VALIDATE_URL; class CreateEcosystemDatabase extends Command { @@ -407,6 +410,12 @@ private function getPackageData(array $userData): ?array } $timestamp = (new DateTimeImmutable())->getTimestamp(); + if (! $userData['homepage'] || ! filter_var($userData['homepage'], FILTER_VALIDATE_URL)) { + $lastVersionData = $packageData['versions'][array_key_first($packageData['versions'])]; + $website = $lastVersionData['homepage'] ?? ''; + } else { + $website = $userData['homepage']; + } return [ 'id' => uniqid($packageData['name']), @@ -424,7 +433,7 @@ private function getPackageData(array $userData): ?array 'category' => $userData['category'], 'packagistUrl' => $userData['packagistUrl'], 'keywords' => $userData['keywords'] !== [] ? $userData['keywords'] : '', - 'website' => isset($userData['homepage']) && $userData['homepage'] !== '' ? $userData['homepage'] : '', + 'website' => $website, 'image' => $this->getSocialPreview( str_replace('https://github.com/', '', $packageData['repository']) ?? $matches[1] ), From d188f98a884829174c234f6e9fdc68211d1f7c65 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 Nov 2024 00:39:34 +0000 Subject: [PATCH 09/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 27 ++++++++------- composer.lock | 66 +++++++++++++++++++------------------ 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index 4a0e35a2..0686005b 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -157,6 +157,7 @@ "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", @@ -857,9 +858,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001673", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001673.tgz", - "integrity": "sha512-WTrjUCSMp3LYX0nE12ECkV0a+e6LC85E0Auz75555/qr78Oc8YWhEPNfDd6SHdtlCMSzqtuXY0uyEMNRcsKpKw==", + "version": "1.0.30001677", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", + "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", "dev": true, "funding": [ { @@ -1170,6 +1171,7 @@ "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "dev": true, "license": "Apache-2.0", + "optional": true, "bin": { "detect-libc": "bin/detect-libc.js" }, @@ -1218,9 +1220,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.47.tgz", - "integrity": "sha512-zS5Yer0MOYw4rtK2iq43cJagHZ8sXN0jDHDKzB+86gSBSAI4v07S97mcq+Gs2vclAxSh1j7vOAHxSVgduiiuVQ==", + "version": "1.5.50", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", + "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", "dev": true, "license": "ISC" }, @@ -2598,7 +2600,8 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true }, "node_modules/node-releases": { "version": "2.0.18", @@ -3132,13 +3135,12 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.80.4", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.4.tgz", - "integrity": "sha512-rhMQ2tSF5CsuuspvC94nPM9rToiAFw2h3JTrLlgmNw1MH79v8Cr3DH6KF6o6r+8oofY3iYVPUf66KzC8yuVN1w==", + "version": "1.80.6", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.6.tgz", + "integrity": "sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==", "dev": true, "license": "MIT", "dependencies": { - "@parcel/watcher": "^2.4.1", "chokidar": "^4.0.0", "immutable": "^4.0.0", "source-map-js": ">=0.6.2 <2.0.0" @@ -3148,6 +3150,9 @@ }, "engines": { "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, "node_modules/sass/node_modules/chokidar": { diff --git a/composer.lock b/composer.lock index 007dedd3..789940c7 100644 --- a/composer.lock +++ b/composer.lock @@ -978,22 +978,22 @@ }, { "name": "laminas/laminas-stratigility", - "version": "3.12.0", + "version": "3.13.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stratigility.git", - "reference": "c8d802a354a7b7ceca0c8ba4b68c365ecafaba64" + "reference": "3df57528b5c8e9d958515c51006825a83f76d62b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stratigility/zipball/c8d802a354a7b7ceca0c8ba4b68c365ecafaba64", - "reference": "c8d802a354a7b7ceca0c8ba4b68c365ecafaba64", + "url": "https://api.github.com/repos/laminas/laminas-stratigility/zipball/3df57528b5c8e9d958515c51006825a83f76d62b", + "reference": "3df57528b5c8e9d958515c51006825a83f76d62b", "shasum": "" }, "require": { "fig/http-message-util": "^1.1", "laminas/laminas-escaper": "^2.10.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "psr/http-message": "^1.0 || ^2.0", "psr/http-server-middleware": "^1.0.2" }, @@ -1002,10 +1002,10 @@ }, "require-dev": { "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-diactoros": "^2.25 || ^3.3.1", - "phpunit/phpunit": "^10.5.27", + "laminas/laminas-diactoros": "^2.25 || ^3.5.0", + "phpunit/phpunit": "^10.5.37", "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.25.0" + "vimeo/psalm": "^5.26.1" }, "suggest": { "psr/http-message-implementation": "Please install a psr/http-message-implementation to consume Stratigility; e.g., laminas/laminas-diactoros" @@ -1053,7 +1053,7 @@ "type": "community_bridge" } ], - "time": "2024-07-16T22:57:16+00:00" + "time": "2024-10-28T11:28:41+00:00" }, { "name": "league/commonmark", @@ -1245,24 +1245,24 @@ }, { "name": "league/plates", - "version": "v3.5.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/thephpleague/plates.git", - "reference": "a6a3238e46c6e19af7318fdc36bfbe49b0620231" + "reference": "12ee65166adbc6fb5916fb80b0c0758e49a2d996" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/plates/zipball/a6a3238e46c6e19af7318fdc36bfbe49b0620231", - "reference": "a6a3238e46c6e19af7318fdc36bfbe49b0620231", + "url": "https://api.github.com/repos/thephpleague/plates/zipball/12ee65166adbc6fb5916fb80b0c0758e49a2d996", + "reference": "12ee65166adbc6fb5916fb80b0c0758e49a2d996", "shasum": "" }, "require": { - "php": "^7.0|^8.0" + "php": "^8.0" }, "require-dev": { "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^11.4", "squizlabs/php_codesniffer": "^3.5" }, "type": "library", @@ -1303,9 +1303,9 @@ ], "support": { "issues": "https://github.com/thephpleague/plates/issues", - "source": "https://github.com/thephpleague/plates/tree/v3.5.0" + "source": "https://github.com/thephpleague/plates/tree/v3.6.0" }, - "time": "2023-01-16T20:25:45+00:00" + "time": "2024-11-02T15:03:35+00:00" }, { "name": "mezzio/mezzio", @@ -5785,16 +5785,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.37", + "version": "10.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c7cffa0efa2b70c22366523e6d804c9419eb2400" + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c7cffa0efa2b70c22366523e6d804c9419eb2400", - "reference": "c7cffa0efa2b70c22366523e6d804c9419eb2400", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", "shasum": "" }, "require": { @@ -5866,7 +5866,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.37" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" }, "funding": [ { @@ -5882,7 +5882,7 @@ "type": "tidelift" } ], - "time": "2024-10-19T13:03:41+00:00" + "time": "2024-10-28T13:06:21+00:00" }, { "name": "psalm/plugin-phpunit", @@ -5950,12 +5950,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "bae581ca4125f92b1ad4d316ac691fa2d5231649" + "reference": "e3b44e38648ef5386687032582759f9c616c8d19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/bae581ca4125f92b1ad4d316ac691fa2d5231649", - "reference": "bae581ca4125f92b1ad4d316ac691fa2d5231649", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e3b44e38648ef5386687032582759f9c616c8d19", + "reference": "e3b44e38648ef5386687032582759f9c616c8d19", "shasum": "" }, "conflict": { @@ -5975,6 +5975,7 @@ "alextselegidis/easyappointments": "<1.5", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", + "ameos/ameos_tarteaucitron": "<1.2.23", "amphp/artax": "<1.0.6|>=2,<2.0.6", "amphp/http": "<=1.7.2|>=2,<=2.1", "amphp/http-client": ">=4,<4.4", @@ -6132,7 +6133,7 @@ "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1", "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", - "ezyang/htmlpurifier": "<4.1.1", + "ezyang/htmlpurifier": "<=4.2", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", "facturascripts/facturascripts": "<=2022.08", "fastly/magento2": "<1.2.26", @@ -6274,6 +6275,7 @@ "laravel/fortify": "<1.11.1", "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", "laravel/laravel": ">=5.4,<5.4.22", + "laravel/reverb": "<1.4", "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", "lavalite/cms": "<=9|==10.1", @@ -6308,7 +6310,7 @@ "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", "mdanter/ecc": "<2", "mediawiki/cargo": "<3.6.1", - "mediawiki/core": "<1.36.2", + "mediawiki/core": "<1.39.5|==1.40", "mediawiki/matomo": "<2.4.3", "mediawiki/semantic-media-wiki": "<4.0.2", "melisplatform/melis-asset-manager": "<5.0.1", @@ -6407,7 +6409,7 @@ "phenx/php-svg-lib": "<0.5.2", "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", "php-mod/curl": "<2.3.2", - "phpbb/phpbb": "<3.2.10|>=3.3,<3.3.1", + "phpbb/phpbb": "<3.3.11", "phpems/phpems": ">=6,<=6.1.3", "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", "phpmailer/phpmailer": "<6.5", @@ -6613,7 +6615,7 @@ "tobiasbg/tablepress": "<=2.0.0.0-RC1", "topthink/framework": "<6.0.17|>=6.1,<=8.0.4", "topthink/think": "<=6.1.1", - "topthink/thinkphp": "<=3.2.3", + "topthink/thinkphp": "<=3.2.3|>=6.1.3,<=8.0.4", "torrentpier/torrentpier": "<=2.4.3", "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", "tribalsystems/zenario": "<=9.7.61188", @@ -6684,7 +6686,7 @@ "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", - "yeswiki/yeswiki": "<4.1", + "yeswiki/yeswiki": "<=4.4.4", "yetiforce/yetiforce-crm": "<=6.4", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", @@ -6774,7 +6776,7 @@ "type": "tidelift" } ], - "time": "2024-10-24T22:04:53+00:00" + "time": "2024-10-31T18:06:19+00:00" }, { "name": "sebastian/cli-parser", From 769a70a7f886cafaf3e3175a75cd16f2e23ad914 Mon Sep 17 00:00:00 2001 From: arhimede Date: Wed, 16 Oct 2024 19:35:44 +0300 Subject: [PATCH 10/38] Wrong pattern of an URL for a blog article Signed-off-by: arhimede --- public/.htaccess | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/.htaccess b/public/.htaccess index cd6355d3..5132b800 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -17,3 +17,6 @@ RewriteRule ^.*$ - [NC,L] RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ RewriteRule ^(.*) - [E=BASE:%1] RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L] + +# Redirect for a blog article that do not follow properly the URL pattern +Redirect 301 /blog/2024-08-05-using-laminas-continuous-integration.md.html /blog/2024-08-05-using-laminas-continuous-integration.html From 7e64063e9b410c40ef61f2fef650a09309bcbb4b Mon Sep 17 00:00:00 2001 From: arhimede Date: Fri, 25 Oct 2024 14:29:38 +0300 Subject: [PATCH 11/38] add article about October 2024 meeting Signed-off-by: arhimede --- ...-summary-of-the-meeting-in-october-2024.md | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md diff --git a/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md b/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md new file mode 100644 index 00000000..9914f33b --- /dev/null +++ b/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md @@ -0,0 +1,48 @@ +--- +id: 2024-10-25-summary-of-the-meeting-in-october-2024 +author: julian +title: 'Summary of the meeting in October 2024' +draft: false +public: true +created: '2024-10-25T11:00:00-01:00' +updated: '2024-10-25T11:00:00-01:00' +tags: + - meeting summary +--- + +On Monday, 7 October 2024, the Technical Steering Committee for the Laminas Project held its monthly meeting. +The topics discussed included: + +- Creating a **marketing and outreach committee**. +- Hiring a **dedicated developer** for the Laminas and Mezzio repositories. + + + +### Marketing and Outreach Committee + +The Laminas Technical Steering Committee (TSC) members have discussed at length the means to build awareness for the Laminas project. +This involves marketing, branding and outreach efforts. +The members considered creating a separate committee from the TSC that would be directly responsible for these activities, while still answering to the TSC. +The new committee's activities would take place in tandem with the technical development of the project. +It would be comprised only of members that are interested in these kinds of activities. + +The main reason for creating a new Marketing and Outreach Committee (MOC) is the decision-making process which is deemed slow by some of the TSC members. +The MOC would only contain individuals who express interest in marketing the Laminas Project, even if this means non-TSC members. +Ultimately, the TSC members agreed to create a small marketing plan to begin with and then evaluate its effectiveness. +Afterwards, a longer-term marketing plan will be considered. + +### Dedicated Developer + +The increasingly complex projects in the current open-source software ecosystem can benefit from dedicated developers to move things forward effectively. +There are several hundred open Pull Requests in the Laminas and Mezzio repositories, some months-old. +This new developer would work in a part-time capacity (2-3 days per week) on managing open items and improving the development flow across Laminas and Mezzio components. + +There are several important aspects in choosing dedicated developers, like their ability to collaborate well with contributors and their technical experience in effectively working on Laminas and Mezzio components. +Rather than fully commit to hiring such individuals and assigning e.g. merging rights, an initial step agreed upon by the TSC members was to only enable triage rights. +This allows for a longer evaluation period to ensure that quality reviews and feedback are delivered. + +### Summary + +Both items on the agenda were discussed in detail, and many relevant points of view were considered. +These items mark a new direction and bringing a new developer on board, so the ultimate decisions must not be taken lightly. +Both have been greenlit, at first with small steps to allow careful evaluation and further discussion in future TSC meetings. \ No newline at end of file From 93ffe62597bccafd38cd2af847ffd6b5bd6baae8 Mon Sep 17 00:00:00 2001 From: arhimede Date: Fri, 25 Oct 2024 15:12:06 +0300 Subject: [PATCH 12/38] add article about October 2024 meeting Signed-off-by: arhimede --- public/.htaccess | 3 --- 1 file changed, 3 deletions(-) diff --git a/public/.htaccess b/public/.htaccess index 5132b800..cd6355d3 100644 --- a/public/.htaccess +++ b/public/.htaccess @@ -17,6 +17,3 @@ RewriteRule ^.*$ - [NC,L] RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ RewriteRule ^(.*) - [E=BASE:%1] RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L] - -# Redirect for a blog article that do not follow properly the URL pattern -Redirect 301 /blog/2024-08-05-using-laminas-continuous-integration.md.html /blog/2024-08-05-using-laminas-continuous-integration.html From ae72ceb7537a7ab48737565234f108e1aa0b60c9 Mon Sep 17 00:00:00 2001 From: Aleksei Khudiakov Date: Tue, 5 Nov 2024 00:29:10 +1000 Subject: [PATCH 13/38] Fix wrong usage of the GHA context in shell. Improve verbiage Signed-off-by: Aleksei Khudiakov --- .github/workflows/pr-autocloser.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr-autocloser.yml b/.github/workflows/pr-autocloser.yml index 19bc17f7..af47c1a1 100644 --- a/.github/workflows/pr-autocloser.yml +++ b/.github/workflows/pr-autocloser.yml @@ -13,8 +13,11 @@ jobs: steps: - name: Comment and close PR run: | - gh pr close "${{ github.event.pull_request.url }}" - --comment "Pull requests to the live branch are not allowed. Use staging branch. Publish via workflow dispatch to Publish to live workflow" + gh pr close "${PR_NUMBER}" \ + --repo "${GH_REPO}" \ + --comment "Pull requests to the master branch are not allowed. Use staging branch. Maintainer can publish staging branch using workflow dispatch at https://github.com/laminas/getlaminas.org/actions/workflows/publish.yml" env: + GH_REPO: ${{ github.repository }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PR_NUMBER: ${{ github.event.pull_request.number }} From 646ac5494560f9bd8c1e9282a973331b44c6313e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 01:33:54 +0000 Subject: [PATCH 14/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 145 +++++++++++++++++++++--------------- composer.lock | 64 ++++++++-------- 2 files changed, 119 insertions(+), 90 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index 0686005b..d613ccf1 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -152,10 +152,11 @@ } }, "node_modules/@parcel/watcher": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.4.1.tgz", - "integrity": "sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.0.tgz", + "integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==", "dev": true, + "hasInstallScript": true, "license": "MIT", "optional": true, "dependencies": { @@ -172,24 +173,25 @@ "url": "https://opencollective.com/parcel" }, "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.4.1", - "@parcel/watcher-darwin-arm64": "2.4.1", - "@parcel/watcher-darwin-x64": "2.4.1", - "@parcel/watcher-freebsd-x64": "2.4.1", - "@parcel/watcher-linux-arm-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-glibc": "2.4.1", - "@parcel/watcher-linux-arm64-musl": "2.4.1", - "@parcel/watcher-linux-x64-glibc": "2.4.1", - "@parcel/watcher-linux-x64-musl": "2.4.1", - "@parcel/watcher-win32-arm64": "2.4.1", - "@parcel/watcher-win32-ia32": "2.4.1", - "@parcel/watcher-win32-x64": "2.4.1" + "@parcel/watcher-android-arm64": "2.5.0", + "@parcel/watcher-darwin-arm64": "2.5.0", + "@parcel/watcher-darwin-x64": "2.5.0", + "@parcel/watcher-freebsd-x64": "2.5.0", + "@parcel/watcher-linux-arm-glibc": "2.5.0", + "@parcel/watcher-linux-arm-musl": "2.5.0", + "@parcel/watcher-linux-arm64-glibc": "2.5.0", + "@parcel/watcher-linux-arm64-musl": "2.5.0", + "@parcel/watcher-linux-x64-glibc": "2.5.0", + "@parcel/watcher-linux-x64-musl": "2.5.0", + "@parcel/watcher-win32-arm64": "2.5.0", + "@parcel/watcher-win32-ia32": "2.5.0", + "@parcel/watcher-win32-x64": "2.5.0" } }, "node_modules/@parcel/watcher-android-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz", + "integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==", "cpu": [ "arm64" ], @@ -208,9 +210,9 @@ } }, "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz", + "integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==", "cpu": [ "arm64" ], @@ -229,9 +231,9 @@ } }, "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz", + "integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==", "cpu": [ "x64" ], @@ -250,9 +252,9 @@ } }, "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz", + "integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==", "cpu": [ "x64" ], @@ -271,9 +273,30 @@ } }, "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz", + "integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz", + "integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==", "cpu": [ "arm" ], @@ -292,9 +315,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz", + "integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==", "cpu": [ "arm64" ], @@ -313,9 +336,9 @@ } }, "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz", + "integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==", "cpu": [ "arm64" ], @@ -334,9 +357,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", - "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz", + "integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==", "cpu": [ "x64" ], @@ -355,9 +378,9 @@ } }, "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.4.1.tgz", - "integrity": "sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz", + "integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==", "cpu": [ "x64" ], @@ -376,9 +399,9 @@ } }, "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz", + "integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==", "cpu": [ "arm64" ], @@ -397,9 +420,9 @@ } }, "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz", + "integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==", "cpu": [ "ia32" ], @@ -418,9 +441,9 @@ } }, "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz", + "integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==", "cpu": [ "x64" ], @@ -858,9 +881,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001680", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "dev": true, "funding": [ { @@ -1220,9 +1243,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", - "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==", + "version": "1.5.55", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", + "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==", "dev": true, "license": "ISC" }, @@ -2810,9 +2833,9 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.48", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz", + "integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==", "dev": true, "funding": [ { @@ -2832,7 +2855,7 @@ "peer": true, "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { diff --git a/composer.lock b/composer.lock index 789940c7..4d3a9237 100644 --- a/composer.lock +++ b/composer.lock @@ -2834,16 +2834,16 @@ }, { "name": "symfony/console", - "version": "v7.1.6", + "version": "v7.1.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57" + "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/bb5192af6edc797cbab5c8e8ecfea2fe5f421e57", - "reference": "bb5192af6edc797cbab5c8e8ecfea2fe5f421e57", + "url": "https://api.github.com/repos/symfony/console/zipball/3284aafcac338b6e86fd955ee4d794cbe434151a", + "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a", "shasum": "" }, "require": { @@ -2907,7 +2907,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.6" + "source": "https://github.com/symfony/console/tree/v7.1.7" }, "funding": [ { @@ -2923,7 +2923,7 @@ "type": "tidelift" } ], - "time": "2024-10-09T08:46:59+00:00" + "time": "2024-11-05T15:34:55+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5026,16 +5026,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.12.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", - "reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -5074,7 +5074,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -5082,7 +5082,7 @@ "type": "tidelift" } ], - "time": "2024-06-12T14:39:25+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "netresearch/jsonmapper", @@ -5950,12 +5950,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "e3b44e38648ef5386687032582759f9c616c8d19" + "reference": "e63317470a1b96346be224a68f9e64567e1001c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e3b44e38648ef5386687032582759f9c616c8d19", - "reference": "e3b44e38648ef5386687032582759f9c616c8d19", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e63317470a1b96346be224a68f9e64567e1001c3", + "reference": "e63317470a1b96346be224a68f9e64567e1001c3", "shasum": "" }, "conflict": { @@ -6140,6 +6140,7 @@ "feehi/cms": "<=2.1.1", "feehi/feehicms": "<=2.1.1", "fenom/fenom": "<=2.12.1", + "filament/actions": ">=3.2,<3.2.123", "filament/infolists": ">=3,<3.2.115", "filament/tables": ">=3,<3.2.115", "filegator/filegator": "<7.8", @@ -6308,6 +6309,7 @@ "matyhtf/framework": "<3.0.6", "mautic/core": "<4.4.13|>=5,<5.1.1", "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", + "maximebf/debugbar": "<1.19", "mdanter/ecc": "<2", "mediawiki/cargo": "<3.6.1", "mediawiki/core": "<1.39.5|==1.40", @@ -6330,7 +6332,7 @@ "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.5|>=4.4.0.0-beta,<4.4.1", + "moodle/moodle": "<4.3.6|>=4.4.0.0-beta,<4.4.2", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", "movingbytes/social-network": "<=1.2.1", @@ -6417,7 +6419,7 @@ "phpmyadmin/phpmyadmin": "<5.2.1", "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", "phpoffice/common": "<0.2.9", - "phpoffice/phpexcel": "<1.8", + "phpoffice/phpexcel": "<1.8.1", "phpoffice/phpspreadsheet": "<1.29.2|>=2,<2.1.1|>=2.2,<2.3", "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", "phpservermon/phpservermon": "<3.6", @@ -6568,7 +6570,8 @@ "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", - "symfony/http-foundation": ">=2,<2.8.52|>=3,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7", + "symfony/http-client": ">=4.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/http-foundation": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", @@ -6576,20 +6579,22 @@ "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/polyfill": ">=1,<1.10", "symfony/polyfill-php55": ">=1,<1.10", + "symfony/process": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", "symfony/routing": ">=2,<2.0.19", + "symfony/runtime": ">=5.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", - "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.4.10|>=7,<7.0.10|>=7.1,<7.1.3", "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", + "symfony/symfony": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", "symfony/translation": ">=2,<2.0.17", "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/ux-autocomplete": "<2.11.2", - "symfony/validator": ">=2,<2.0.24|>=2.1,<2.1.12|>=2.2,<2.2.5|>=2.3,<2.3.3", + "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/webhook": ">=6.3,<6.3.8", @@ -6622,7 +6627,7 @@ "truckersmp/phpwhois": "<=4.3.1", "ttskch/pagination-service-provider": "<1", "twbs/bootstrap": "<=3.4.1|>=4,<=4.6.2", - "twig/twig": "<1.44.8|>=2,<2.16.1|>=3,<3.11.1|>=3.12,<3.14", + "twig/twig": "<3.11.2|>=3.12,<3.14.1", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<10.4.46|>=11,<11.5.40|>=12,<12.4.21|>=13,<13.3.1", "typo3/cms-core": "<=8.7.56|>=9,<=9.5.47|>=10,<=10.4.44|>=11,<=11.5.36|>=12,<=12.4.14|>=13,<=13.1", @@ -6641,6 +6646,7 @@ "ua-parser/uap-php": "<3.8", "uasoft-indonesia/badaso": "<=2.9.7", "unisharp/laravel-filemanager": "<2.6.4", + "unopim/unopim": "<0.1.4", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", @@ -6776,7 +6782,7 @@ "type": "tidelift" } ], - "time": "2024-10-31T18:06:19+00:00" + "time": "2024-11-07T19:04:57+00:00" }, { "name": "sebastian/cli-parser", @@ -7903,16 +7909,16 @@ }, { "name": "symfony/process", - "version": "v6.4.13", + "version": "v6.4.14", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1f9f59b46880201629df3bd950fc5ae8c55b960f" + "reference": "25214adbb0996d18112548de20c281be9f27279f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1f9f59b46880201629df3bd950fc5ae8c55b960f", - "reference": "1f9f59b46880201629df3bd950fc5ae8c55b960f", + "url": "https://api.github.com/repos/symfony/process/zipball/25214adbb0996d18112548de20c281be9f27279f", + "reference": "25214adbb0996d18112548de20c281be9f27279f", "shasum": "" }, "require": { @@ -7944,7 +7950,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.13" + "source": "https://github.com/symfony/process/tree/v6.4.14" }, "funding": [ { @@ -7960,7 +7966,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:18:03+00:00" + "time": "2024-11-06T09:25:01+00:00" }, { "name": "theseer/tokenizer", From 0dc8ec7bdc5178044e71664a8083a4fdf538c94a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 11 Nov 2024 12:59:04 +0000 Subject: [PATCH 15/38] Update dependency laminas/laminas-config-aggregator to ^1.16.0 | datasource | package | from | to | | ---------- | --------------------------------- | ------ | ------ | | packagist | laminas/laminas-config-aggregator | 1.15.0 | 1.16.0 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- composer.json | 2 +- composer.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/composer.json b/composer.json index c4912e5a..f2d4f11a 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "dflydev/fig-cookies": "^3.1.0", "laminas/laminas-cli": "^1.10.0", "laminas/laminas-component-installer": "^3.4.0", - "laminas/laminas-config-aggregator": "^1.15.0", + "laminas/laminas-config-aggregator": "^1.16.0", "laminas/laminas-diactoros": "^3.5.0", "laminas/laminas-feed": "^2.23.0", "laminas/laminas-paginator": "^2.19.0", diff --git a/composer.lock b/composer.lock index 4d3a9237..aa4e8ce9 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": "df64e3401b419d19a9e9121990414231", + "content-hash": "3ce42b4d5d230034b7c89bb7f923543e", "packages": [ { "name": "brick/varexporter", @@ -385,16 +385,16 @@ }, { "name": "laminas/laminas-config-aggregator", - "version": "1.15.0", + "version": "1.16.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-config-aggregator.git", - "reference": "102e048734413a4499846571b156aeaa6c2aba56" + "reference": "25a1b50d957ff8eaaaae9ae07dd22904ebbc9431" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-config-aggregator/zipball/102e048734413a4499846571b156aeaa6c2aba56", - "reference": "102e048734413a4499846571b156aeaa6c2aba56", + "url": "https://api.github.com/repos/laminas/laminas-config-aggregator/zipball/25a1b50d957ff8eaaaae9ae07dd22904ebbc9431", + "reference": "25a1b50d957ff8eaaaae9ae07dd22904ebbc9431", "shasum": "" }, "require": { @@ -408,7 +408,7 @@ "zendframework/zend-config-aggregator": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", + "laminas/laminas-coding-standard": "~3.0.0", "laminas/laminas-config": "^3.9.0", "phpunit/phpunit": "^10.5.11", "psalm/plugin-phpunit": "^0.19.0", @@ -449,7 +449,7 @@ "type": "community_bridge" } ], - "time": "2024-05-12T10:04:30+00:00" + "time": "2024-11-11T11:21:55+00:00" }, { "name": "laminas/laminas-diactoros", From d2f16d22de6d920c45a222e5f04ade0292e32619 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 17 Nov 2024 13:55:21 +0000 Subject: [PATCH 16/38] Update dependency laminas/laminas-config-aggregator to ^1.17.0 | datasource | package | from | to | | ---------- | --------------------------------- | ------ | ------ | | packagist | laminas/laminas-config-aggregator | 1.16.0 | 1.17.0 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- composer.json | 2 +- composer.lock | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/composer.json b/composer.json index f2d4f11a..e814c62c 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "dflydev/fig-cookies": "^3.1.0", "laminas/laminas-cli": "^1.10.0", "laminas/laminas-component-installer": "^3.4.0", - "laminas/laminas-config-aggregator": "^1.16.0", + "laminas/laminas-config-aggregator": "^1.17.0", "laminas/laminas-diactoros": "^3.5.0", "laminas/laminas-feed": "^2.23.0", "laminas/laminas-paginator": "^2.19.0", diff --git a/composer.lock b/composer.lock index aa4e8ce9..aecde06a 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": "3ce42b4d5d230034b7c89bb7f923543e", + "content-hash": "ac6807ea565135dacd76f0773debfd33", "packages": [ { "name": "brick/varexporter", @@ -385,22 +385,22 @@ }, { "name": "laminas/laminas-config-aggregator", - "version": "1.16.0", + "version": "1.17.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-config-aggregator.git", - "reference": "25a1b50d957ff8eaaaae9ae07dd22904ebbc9431" + "reference": "0a70bfa21225c7c7075d1dac4a441a76b2ac49e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-config-aggregator/zipball/25a1b50d957ff8eaaaae9ae07dd22904ebbc9431", - "reference": "25a1b50d957ff8eaaaae9ae07dd22904ebbc9431", + "url": "https://api.github.com/repos/laminas/laminas-config-aggregator/zipball/0a70bfa21225c7c7075d1dac4a441a76b2ac49e7", + "reference": "0a70bfa21225c7c7075d1dac4a441a76b2ac49e7", "shasum": "" }, "require": { "brick/varexporter": "^0.5.0 || ^0.4.0", "laminas/laminas-stdlib": "^3.18.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "webimpress/safe-writer": "^2.2.0" }, "conflict": { @@ -410,7 +410,7 @@ "require-dev": { "laminas/laminas-coding-standard": "~3.0.0", "laminas/laminas-config": "^3.9.0", - "phpunit/phpunit": "^10.5.11", + "phpunit/phpunit": "^10.5.38", "psalm/plugin-phpunit": "^0.19.0", "vimeo/psalm": "^5.22.2" }, @@ -449,7 +449,7 @@ "type": "community_bridge" } ], - "time": "2024-11-11T11:21:55+00:00" + "time": "2024-11-17T10:16:45+00:00" }, { "name": "laminas/laminas-diactoros", From 061cc33d65b7d0cf69652f4d48188b5a363852bb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 18 Nov 2024 02:19:02 +0000 Subject: [PATCH 17/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 32 +++++------ composer.lock | 111 ++++++++++++++++++------------------ 2 files changed, 73 insertions(+), 70 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index d613ccf1..b1f83d61 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -1243,9 +1243,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.55", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", - "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==", + "version": "1.5.62", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz", + "integrity": "sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==", "dev": true, "license": "ISC" }, @@ -2188,9 +2188,9 @@ } }, "node_modules/immutable": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.7.tgz", - "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.2.tgz", + "integrity": "sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==", "dev": true, "license": "MIT" }, @@ -2833,9 +2833,9 @@ } }, "node_modules/postcss": { - "version": "8.4.48", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.48.tgz", - "integrity": "sha512-GCRK8F6+Dl7xYniR5a4FYbpBzU8XnZVeowqsQFYdcXuSbChgiks7qybSkbvnaeqv0G0B+dd9/jJgH8kkLDQeEA==", + "version": "8.4.49", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -3158,14 +3158,14 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.80.6", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.80.6.tgz", - "integrity": "sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==", + "version": "1.81.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.81.0.tgz", + "integrity": "sha512-Q4fOxRfhmv3sqCLoGfvrC9pRV8btc0UtqL9mN6Yrv6Qi9ScL55CVH1vlPP863ISLEEMNLLuu9P+enCeGHlnzhA==", "dev": true, "license": "MIT", "dependencies": { "chokidar": "^4.0.0", - "immutable": "^4.0.0", + "immutable": "^5.0.2", "source-map-js": ">=0.6.2 <2.0.0" }, "bin": { @@ -3301,9 +3301,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", + "version": "2.20.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz", + "integrity": "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/composer.lock b/composer.lock index aecde06a..dde6c4cc 100644 --- a/composer.lock +++ b/composer.lock @@ -1869,16 +1869,16 @@ }, { "name": "monolog/monolog", - "version": "3.7.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8" + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/f4393b648b78a5408747de94fca38beb5f7e9ef8", - "reference": "f4393b648b78a5408747de94fca38beb5f7e9ef8", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", + "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", "shasum": "" }, "require": { @@ -1898,12 +1898,14 @@ "guzzlehttp/psr7": "^2.2", "mongodb/mongodb": "^1.8", "php-amqplib/php-amqplib": "~2.4 || ^3", - "phpstan/phpstan": "^1.9", - "phpstan/phpstan-deprecation-rules": "^1.0", - "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "^10.5.17", + "php-console/php-console": "^3.1.8", + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^10.5.17 || ^11.0.7", "predis/predis": "^1.1 || ^2", - "ruflin/elastica": "^7", + "rollbar/rollbar": "^4.0", + "ruflin/elastica": "^7 || ^8", "symfony/mailer": "^5.4 || ^6", "symfony/mime": "^5.4 || ^6" }, @@ -1954,7 +1956,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.7.0" + "source": "https://github.com/Seldaek/monolog/tree/3.8.0" }, "funding": [ { @@ -1966,7 +1968,7 @@ "type": "tidelift" } ], - "time": "2024-06-28T09:40:51+00:00" + "time": "2024-11-12T13:57:08+00:00" }, { "name": "nette/schema", @@ -2834,16 +2836,16 @@ }, { "name": "symfony/console", - "version": "v7.1.7", + "version": "v7.1.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a" + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3284aafcac338b6e86fd955ee4d794cbe434151a", - "reference": "3284aafcac338b6e86fd955ee4d794cbe434151a", + "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", "shasum": "" }, "require": { @@ -2907,7 +2909,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.7" + "source": "https://github.com/symfony/console/tree/v7.1.8" }, "funding": [ { @@ -2923,7 +2925,7 @@ "type": "tidelift" } ], - "time": "2024-11-05T15:34:55+00:00" + "time": "2024-11-06T14:23:19+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3631,16 +3633,16 @@ }, { "name": "symfony/string", - "version": "v7.1.6", + "version": "v7.1.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626" + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/61b72d66bf96c360a727ae6232df5ac83c71f626", - "reference": "61b72d66bf96c360a727ae6232df5ac83c71f626", + "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", "shasum": "" }, "require": { @@ -3698,7 +3700,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.6" + "source": "https://github.com/symfony/string/tree/v7.1.8" }, "funding": [ { @@ -3714,7 +3716,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-11-13T13:31:21+00:00" }, { "name": "symfony/yaml", @@ -4197,16 +4199,16 @@ }, { "name": "composer/pcre", - "version": "3.3.1", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4" + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/63aaeac21d7e775ff9bc9d45021e1745c97521c4", - "reference": "63aaeac21d7e775ff9bc9d45021e1745c97521c4", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { @@ -4216,8 +4218,8 @@ "phpstan/phpstan": "<1.11.10" }, "require-dev": { - "phpstan/phpstan": "^1.11.10", - "phpstan/phpstan-strict-rules": "^1.1", + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", "phpunit/phpunit": "^8 || ^9" }, "type": "library", @@ -4256,7 +4258,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.1" + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { @@ -4272,7 +4274,7 @@ "type": "tidelift" } ], - "time": "2024-08-27T18:44:43+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { "name": "composer/semver", @@ -5950,12 +5952,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "e63317470a1b96346be224a68f9e64567e1001c3" + "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/e63317470a1b96346be224a68f9e64567e1001c3", - "reference": "e63317470a1b96346be224a68f9e64567e1001c3", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", + "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", "shasum": "" }, "conflict": { @@ -6001,6 +6003,7 @@ "azuracast/azuracast": "<0.18.3", "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2", "backpack/crud": "<3.4.9", + "backpack/filemanager": "<3.0.9", "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", "badaso/core": "<2.7", "bagisto/bagisto": "<2.1", @@ -6064,7 +6067,7 @@ "contao/managed-edition": "<=1.5", "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", - "craftcms/cms": "<4.6.2|>=5,<=5.2.2", + "craftcms/cms": "<=4.12.6.1|>=5,<=5.4.7.1", "croogo/croogo": "<4", "cuyz/valinor": "<0.12", "czim/file-handling": "<1.5|>=2,<2.3", @@ -6274,7 +6277,7 @@ "lara-zeus/artemis": ">=1,<=1.0.6", "lara-zeus/dynamic-dashboard": ">=3,<=3.0.1", "laravel/fortify": "<1.11.1", - "laravel/framework": "<6.20.44|>=7,<7.30.6|>=8,<8.75", + "laravel/framework": "<6.20.45|>=7,<7.30.7|>=8,<8.83.28|>=9,<9.52.17|>=10,<10.48.23|>=11,<11.31", "laravel/laravel": ">=5.4,<5.4.22", "laravel/reverb": "<1.4", "laravel/socialite": ">=1,<2.0.10", @@ -6332,7 +6335,7 @@ "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.6|>=4.4.0.0-beta,<4.4.2", + "moodle/moodle": "<4.3.6|>=4.4,<4.4.4", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", "movingbytes/social-network": "<=1.2.1", @@ -6380,7 +6383,7 @@ "openmage/magento-lts": "<20.10.1", "opensolutions/vimbadmin": "<=3.0.15", "opensource-workshop/connect-cms": "<1.7.2|>=2,<2.3.2", - "orchid/platform": ">=9,<9.4.4|>=14.0.0.0-alpha4,<14.5", + "orchid/platform": ">=8,<14.43", "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", "oro/crm": ">=1.7,<1.7.4|>=3.1,<4.1.17|>=4.2,<4.2.7", @@ -6570,7 +6573,7 @@ "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", - "symfony/http-client": ">=4.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/http-client": ">=4.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/http-foundation": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", @@ -6588,9 +6591,9 @@ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.3.2|>=5.4,<5.4.31|>=6,<6.3.8", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/translation": ">=2,<2.0.17", "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/ux-autocomplete": "<2.11.2", @@ -6646,7 +6649,7 @@ "ua-parser/uap-php": "<3.8", "uasoft-indonesia/badaso": "<=2.9.7", "unisharp/laravel-filemanager": "<2.6.4", - "unopim/unopim": "<0.1.4", + "unopim/unopim": "<0.1.5", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", @@ -6782,7 +6785,7 @@ "type": "tidelift" } ], - "time": "2024-11-07T19:04:57+00:00" + "time": "2024-11-13T19:05:18+00:00" }, { "name": "sebastian/cli-parser", @@ -7763,16 +7766,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.10.3", + "version": "3.11.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "62d32998e820bddc40f99f8251958aed187a5c9c" + "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/62d32998e820bddc40f99f8251958aed187a5c9c", - "reference": "62d32998e820bddc40f99f8251958aed187a5c9c", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", + "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", "shasum": "" }, "require": { @@ -7839,7 +7842,7 @@ "type": "open_collective" } ], - "time": "2024-09-18T10:38:58+00:00" + "time": "2024-11-16T12:02:36+00:00" }, { "name": "symfony/filesystem", @@ -7909,16 +7912,16 @@ }, { "name": "symfony/process", - "version": "v6.4.14", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "25214adbb0996d18112548de20c281be9f27279f" + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/25214adbb0996d18112548de20c281be9f27279f", - "reference": "25214adbb0996d18112548de20c281be9f27279f", + "url": "https://api.github.com/repos/symfony/process/zipball/3cb242f059c14ae08591c5c4087d1fe443564392", + "reference": "3cb242f059c14ae08591c5c4087d1fe443564392", "shasum": "" }, "require": { @@ -7950,7 +7953,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.4.14" + "source": "https://github.com/symfony/process/tree/v6.4.15" }, "funding": [ { @@ -7966,7 +7969,7 @@ "type": "tidelift" } ], - "time": "2024-11-06T09:25:01+00:00" + "time": "2024-11-06T14:19:14+00:00" }, { "name": "theseer/tokenizer", From 118809839b9b9e70cba949b51658520f1811c469 Mon Sep 17 00:00:00 2001 From: arhimede Date: Fri, 15 Nov 2024 16:09:21 +0200 Subject: [PATCH 18/38] add article about November 2024 meeting Signed-off-by: arhimede --- ...summary-of-the-meeting-in-november-2024.md | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md diff --git a/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md new file mode 100644 index 00000000..15104b56 --- /dev/null +++ b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md @@ -0,0 +1,79 @@ +--- +id: 2024-11-18-summary-of-the-meeting-in-november-2024 +author: julian +title: 'Summary of the meeting in November 2024' +draft: false +public: true +created: '2024-11-18T11:00:00-01:00' +updated: '2024-11-18T11:00:00-01:00' +tags: + - meeting summary +--- + +On Monday, 4 November 2024, the Technical Steering Committee for the Laminas Project held its monthly meeting. The topics discussed included: + +- Abandoning several Laminas packages. +- Financing of the book [**Mezzio Essentials**](https://mezzioessentials.com/). + + +### Abandoning several Laminas packages + +The ever-changing PHP ecosystem means that a package must receive regular attention due to updates in the PHP language and its 3rd-party dependencies. +The most vulnerable to these changes are the legacy packages. +Eventually, it becomes too costly to maintain them. +The best solution becomes to abandon them, mark them archived and recommend viable alternatives for the systems that still use them. + +#### Abandoning/archiving Laminas Oauth + +The Laminas Technical Steering Committee (TSC) members first considered Laminas Oauth (laminas/laminas-oauth) for archival. +There are no resources for its maintenance and actively-maintained alternatives are available (Oauth 2 and OIDC). +The members swiftly decided to archive laminas-oauth with a poll on the day following the TSC meeting. + +#### Abandoning/archiving legacy libraries + +Several other legacy libraries were also mentioned as eligible to be archived or abandoned: + +- laminas-barcode +- laminas-config +- laminas-config-aggregator-modulemanager +- laminas-dom +- laminas-file +- laminas-http +- laminas-json +- laminas-loader +- laminas-log +- laminas-math +- laminas-memory +- laminas-paginator-adapter-laminasdb +- laminas-progressbar +- laminas-tag +- laminas-text +- laminas-uri +- laminas-xml +- laminas-xml2json +- laminas-zendframework-bridge + +Most likely, **laminas-http**, **laminas-uri** and **laminas-xml** will be left active. +Still, every package will have its own poll available for voting by the TSC members. +This topic will be revisited on the following TSC meeting to review the poll results and act upon them. + +### Financing of the Book "Mezzio Essentials" + +The book "Mezzio Essentials" has been welcomed by the PHP community as being essential reading to understand microframeworks, middlewares, PSR's, Mezzio's core components and much more. +The book contains both theoretical knowledge and a lengthly practical example, a step by step guide for building an application, first manually, then by using the Mezzio Skeleton Installer. +While it doesn't claim to be exhaustive, this book is a reliable starting point for the theoretical and practical understanding of using Mezzio Framework. + +The book needs a thorough review and updates to take advantage of the current state of the Mezzio Framework. +The TSC members considered financing this effort. +More details must first be discussed with the book's author, Matthew Setter, before the topic is discussed further in the following TSC meeting. + +#### Summary + +While maintaining a long and encompassing list of packages is desirable, the cost of maintaining them must also be considered. +Other developer teams create similar packages and have more resources to keep them up to date, which makes them a better choice for their less-used Laminas alternatives. +The TSC members are carefully considering their many packages and pruning the ones not worth keeping active. + +All developers can benefit from a well-written book on a given framework. +The TSC members understand this well and are willing to put the Laminas organization's funds to help create this beneficial tool for all developers who use the Mezzio Framework. + +This TSC meeting didn't see a lot of definitive decisions, but the importance of the topics justifies the extra time dedicated to ensuring any decision is sound. From 019c78f85415a09ee37edc081e350fec89273cb6 Mon Sep 17 00:00:00 2001 From: arhimede Date: Fri, 15 Nov 2024 18:48:05 +0200 Subject: [PATCH 19/38] complete the article with other news Signed-off-by: arhimede --- ...summary-of-the-meeting-in-november-2024.md | 81 ++++++++++++++----- 1 file changed, 61 insertions(+), 20 deletions(-) diff --git a/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md index 15104b56..aa89b542 100644 --- a/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md +++ b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md @@ -25,7 +25,7 @@ The best solution becomes to abandon them, mark them archived and recommend viab #### Abandoning/archiving Laminas Oauth -The Laminas Technical Steering Committee (TSC) members first considered Laminas Oauth (laminas/laminas-oauth) for archival. +The Laminas Technical Steering Committee (TSC) members first considered Laminas Oauth (`laminas/laminas-oauth`) for archival. There are no resources for its maintenance and actively-maintained alternatives are available (Oauth 2 and OIDC). The members swiftly decided to archive laminas-oauth with a poll on the day following the TSC meeting. @@ -33,25 +33,25 @@ The members swiftly decided to archive laminas-oauth with a poll on the day foll Several other legacy libraries were also mentioned as eligible to be archived or abandoned: -- laminas-barcode -- laminas-config -- laminas-config-aggregator-modulemanager -- laminas-dom -- laminas-file -- laminas-http -- laminas-json -- laminas-loader -- laminas-log -- laminas-math -- laminas-memory -- laminas-paginator-adapter-laminasdb -- laminas-progressbar -- laminas-tag -- laminas-text -- laminas-uri -- laminas-xml -- laminas-xml2json -- laminas-zendframework-bridge +- `laminas-barcode` +- `laminas-config` +- `laminas-config-aggregator-modulemanager` +- `laminas-dom` +- `laminas-file` +- `laminas-http` +- `laminas-json` +- `laminas-loader` +- `laminas-log` +- `laminas-math` +- `laminas-memory` +- `laminas-paginator-adapter-laminasdb` +- `laminas-progressbar` +- `laminas-tag` +- `laminas-text` +- `laminas-uri` +- `laminas-xml` +- `laminas-xml2json` +- `laminas-zendframework-bridge` Most likely, **laminas-http**, **laminas-uri** and **laminas-xml** will be left active. Still, every package will have its own poll available for voting by the TSC members. @@ -77,3 +77,44 @@ All developers can benefit from a well-written book on a given framework. The TSC members understand this well and are willing to put the Laminas organization's funds to help create this beneficial tool for all developers who use the Mezzio Framework. This TSC meeting didn't see a lot of definitive decisions, but the importance of the topics justifies the extra time dedicated to ensuring any decision is sound. + +### Other News + +#### Laminas Validator Version 3 Released + +We [released version 3](https://github.com/laminas/laminas-validator/releases/tag/3.0.0) of `laminas-validator` last month with nearly 100 PR's merged. + +Support for version 3 in other components is still in the works. The following libraries still need major releases to gain compatibility with validator v3 and in most cases, Service Manager v4: + +- `laminas-form` +- `laminas-i18n` +- `laminas-inputfilter` +- `laminas-i18n-phone-number` +- `laminas-i18n-mvc` +- `laminas-i18n-view` +- `laminas-navigation` +- `laminas-session` +- `laminas-authentication` +- and more… + +Please do try out the new version where possible and let us know how you get on in Slack, and any help you can provide with working on the dependents is appreciated! + +#### Laminas Filter Version 3 + +Work on the next major version of `laminas-filter` is progressing well. +We've been modernising and refactoring all the filters so that they are largely immutable, improving type safety and predictability. + +When it's released `laminas-filter` will support Laminas Service Manager v4 and unlocks continued work on the many dependent libraries, most importantly Laminas Input Filter which will be next in line. + +We welcome contributions to help us get Laminas Filter over the line and there is a [handy todo list](https://github.com/laminas/laminas-filter/issues/177) you can consult to see if there's anything you can help with. + +#### Getting Ready for PHP 8.4 + +Most Laminas and Mezzio components are now 8.4 compatible, ahead of the PHP 8.4 general release. + +You can find the status of PHP 8.4 support in these projects: + +- [8.4 Support in Mezzio](https://github.com/orgs/mezzio/projects/8) +- [8.4 Support in Laminas](https://github.com/orgs/laminas/projects/37) + +As always, PRs are welcome 👍 From 6f6a545cd92ec8619388bc9230255ec95e5941d0 Mon Sep 17 00:00:00 2001 From: arhimede Date: Mon, 18 Nov 2024 17:18:09 +0200 Subject: [PATCH 20/38] removed other news Signed-off-by: arhimede --- ...summary-of-the-meeting-in-november-2024.md | 41 ------------------- 1 file changed, 41 deletions(-) diff --git a/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md index aa89b542..03a0ab25 100644 --- a/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md +++ b/data/blog/2024/2024-11-18-summary-of-the-meeting-in-november-2024.md @@ -77,44 +77,3 @@ All developers can benefit from a well-written book on a given framework. The TSC members understand this well and are willing to put the Laminas organization's funds to help create this beneficial tool for all developers who use the Mezzio Framework. This TSC meeting didn't see a lot of definitive decisions, but the importance of the topics justifies the extra time dedicated to ensuring any decision is sound. - -### Other News - -#### Laminas Validator Version 3 Released - -We [released version 3](https://github.com/laminas/laminas-validator/releases/tag/3.0.0) of `laminas-validator` last month with nearly 100 PR's merged. - -Support for version 3 in other components is still in the works. The following libraries still need major releases to gain compatibility with validator v3 and in most cases, Service Manager v4: - -- `laminas-form` -- `laminas-i18n` -- `laminas-inputfilter` -- `laminas-i18n-phone-number` -- `laminas-i18n-mvc` -- `laminas-i18n-view` -- `laminas-navigation` -- `laminas-session` -- `laminas-authentication` -- and more… - -Please do try out the new version where possible and let us know how you get on in Slack, and any help you can provide with working on the dependents is appreciated! - -#### Laminas Filter Version 3 - -Work on the next major version of `laminas-filter` is progressing well. -We've been modernising and refactoring all the filters so that they are largely immutable, improving type safety and predictability. - -When it's released `laminas-filter` will support Laminas Service Manager v4 and unlocks continued work on the many dependent libraries, most importantly Laminas Input Filter which will be next in line. - -We welcome contributions to help us get Laminas Filter over the line and there is a [handy todo list](https://github.com/laminas/laminas-filter/issues/177) you can consult to see if there's anything you can help with. - -#### Getting Ready for PHP 8.4 - -Most Laminas and Mezzio components are now 8.4 compatible, ahead of the PHP 8.4 general release. - -You can find the status of PHP 8.4 support in these projects: - -- [8.4 Support in Mezzio](https://github.com/orgs/mezzio/projects/8) -- [8.4 Support in Laminas](https://github.com/orgs/laminas/projects/37) - -As always, PRs are welcome 👍 From 319ac015a3dc0ddd8a9fefdaa1e28bfe2a43d558 Mon Sep 17 00:00:00 2001 From: George Steel Date: Mon, 18 Nov 2024 16:01:23 +0000 Subject: [PATCH 21/38] Add new article about October developments Signed-off-by: George Steel --- data/blog/2024/2024-11-18-october-news.md | 50 +++++++++++++++++++++++ data/blog/authors/george.yml | 4 ++ 2 files changed, 54 insertions(+) create mode 100644 data/blog/2024/2024-11-18-october-news.md create mode 100644 data/blog/authors/george.yml diff --git a/data/blog/2024/2024-11-18-october-news.md b/data/blog/2024/2024-11-18-october-news.md new file mode 100644 index 00000000..ab086896 --- /dev/null +++ b/data/blog/2024/2024-11-18-october-news.md @@ -0,0 +1,50 @@ +--- +id: 2024-11-18-october-development-news +author: george +title: 'October 2024 Development News' +draft: false +public: true +created: '2024-11-18T11:00:00-01:00' +updated: '2024-11-18T11:00:00-01:00' +tags: + - development news +--- + +## Laminas Validator Version 3 Released + +We [released version 3](https://github.com/laminas/laminas-validator/releases/tag/3.0.0) of `laminas-validator` in October with nearly 100 PR's merged. + +Support for version 3 in other components is still in the works. The following libraries still need major releases to gain compatibility with validator v3 _(and in most cases, Service Manager v4)_: + +- `laminas-form` +- `laminas-i18n` +- `laminas-inputfilter` +- `laminas-i18n-phone-number` +- `laminas-i18n-mvc` +- `laminas-i18n-view` +- `laminas-navigation` +- `laminas-session` +- `laminas-authentication` +- and more… + +Please do try out the new version where possible and let us know how you get on in Slack, and any help you can provide with working on the dependents is appreciated! + +## Laminas Filter Version 3 + +Work on the [next major version](https://github.com/laminas/laminas-filter/milestone/4) of `laminas-filter` is progressing well. +We've been modernising and refactoring all the filters so that they are largely immutable, improving type safety and predictability with over 50 PRs merged so far. + +When it's released `laminas-filter` will support Laminas Service Manager v4 and unlocks continued work on the many dependent libraries, most importantly Laminas Input Filter which will be next in line. + +We welcome contributions to help us get Laminas Filter over the line and there is a [handy todo list](https://github.com/laminas/laminas-filter/issues/177) you can consult to see if there's anything you can help with. + +## Getting Ready for PHP 8.4 + +Most Laminas and Mezzio components are now 8.4 compatible, ahead of the PHP 8.4 general release. + +You can find the status of PHP 8.4 support in these projects: + +- [8.4 Support in Mezzio](https://github.com/orgs/mezzio/projects/8) +- [8.4 Support in Laminas](https://github.com/orgs/laminas/projects/37) + +As always, PRs are welcome 👍 diff --git a/data/blog/authors/george.yml b/data/blog/authors/george.yml new file mode 100644 index 00000000..ff52f2c5 --- /dev/null +++ b/data/blog/authors/george.yml @@ -0,0 +1,4 @@ +id: george +name: 'George Steel' +email: gsteel@gmail.com +uri: 'https://github.com/gsteel' From 902e0d2ef7d38f89cbda94942d801fa25de181ca Mon Sep 17 00:00:00 2001 From: arhimede Date: Tue, 19 Nov 2024 13:13:30 +0200 Subject: [PATCH 22/38] fix missing extend tag. Add markdown linting Signed-off-by: arhimede --- .markdownlint.json | 4 ++++ data/blog/2024/2024-11-18-october-news.md | 12 +++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 .markdownlint.json diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000..3cbcbe14 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,4 @@ +{ + "default": true, + "MD013": false +} \ No newline at end of file diff --git a/data/blog/2024/2024-11-18-october-news.md b/data/blog/2024/2024-11-18-october-news.md index ab086896..bdf8068a 100644 --- a/data/blog/2024/2024-11-18-october-news.md +++ b/data/blog/2024/2024-11-18-october-news.md @@ -10,7 +10,13 @@ tags: - development news --- -## Laminas Validator Version 3 Released +Laminas Validator Version 3 Released and being implemented in libraries that use it. +Adding support for Laminas Service Manager v4 in laminas-filter is in progress. +Check here the PHP 8.4 compatibility roadmap for Laminas and Mezzio components. + + + +### Laminas Validator Version 3 Released We [released version 3](https://github.com/laminas/laminas-validator/releases/tag/3.0.0) of `laminas-validator` in October with nearly 100 PR's merged. @@ -29,7 +35,7 @@ Support for version 3 in other components is still in the works. The following l Please do try out the new version where possible and let us know how you get on in Slack, and any help you can provide with working on the dependents is appreciated! -## Laminas Filter Version 3 +### Laminas Filter Version 3 Work on the [next major version](https://github.com/laminas/laminas-filter/milestone/4) of `laminas-filter` is progressing well. We've been modernising and refactoring all the filters so that they are largely immutable, improving type safety and predictability with over 50 PRs merged so far. @@ -38,7 +44,7 @@ When it's released `laminas-filter` will support Laminas Service Manager v4 and We welcome contributions to help us get Laminas Filter over the line and there is a [handy todo list](https://github.com/laminas/laminas-filter/issues/177) you can consult to see if there's anything you can help with. -## Getting Ready for PHP 8.4 +### Getting Ready for PHP 8.4 Most Laminas and Mezzio components are now 8.4 compatible, ahead of the PHP 8.4 general release. From d939eac88eb71458fefc288483d230eda5961e47 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Thu, 28 Nov 2024 12:26:45 +0200 Subject: [PATCH 23/38] added linting action && fixed linting errors Signed-off-by: Jurj-Bogdan --- .github/workflows/markdown-linting.yml | 21 +++ COPYRIGHT.md | 2 +- LICENSE.md | 2 +- README.md | 24 ++-- data/advisories/LP-2020-01.md | 2 +- data/advisories/LP-2020-02.md | 2 +- data/advisories/LP-2022-01.md | 2 +- data/advisories/LP-2022-02.md | 2 +- data/advisories/LP-2023-01.md | 3 +- ...-12-31-out-with-the-old-in-with-the-new.md | 120 +++++++++--------- .../2020-03-09-transferring-zf-to-laminas.md | 33 +++-- ...nel-a-replacement-for-laminas-api-tools.md | 3 +- ...nance-status-of-laminas-mezzio-packages.md | 2 +- ...05-using-laminas-continuous-integration.md | 6 +- ...inas-continuous-delivery-and-deployment.md | 2 +- ...-summary-of-the-meeting-in-october-2024.md | 2 +- 16 files changed, 123 insertions(+), 105 deletions(-) create mode 100644 .github/workflows/markdown-linting.yml diff --git a/.github/workflows/markdown-linting.yml b/.github/workflows/markdown-linting.yml new file mode 100644 index 00000000..eefc2a6b --- /dev/null +++ b/.github/workflows/markdown-linting.yml @@ -0,0 +1,21 @@ +name: "Markdown files linting" + +on: + pull_request: + push: + branches: + tags: + +jobs: + linting: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DavidAnson/markdownlint-cli2-action@v18 + with: + config: '.markdownlint.json' + globs: | + **/*.md + !README.md + !bootstrap + !public diff --git a/COPYRIGHT.md b/COPYRIGHT.md index 0a8cccc0..7a65a906 100644 --- a/COPYRIGHT.md +++ b/COPYRIGHT.md @@ -1 +1 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) +# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. () diff --git a/LICENSE.md b/LICENSE.md index 10b40f14..20931766 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. +# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 9e0d37c2..2a2cd498 100644 --- a/README.md +++ b/README.md @@ -30,28 +30,28 @@ RELEASE_FEED_TOKEN=aaaabbbbccccddddeeeeffffgggg0000 Second, install dependencies: ```bash -$ composer install +composer install ``` Third, put the application in development mode: ```bash -$ ./vendor/bin/laminas-development-mode enable +./vendor/bin/laminas-development-mode enable ``` Fourth, prepare the blog and security announcements: ```bash -$ mkdir -p var/blog/feeds -$ mkdir -p public/js -$ composer build +mkdir -p var/blog/feeds +mkdir -p public/js +composer build ``` Finally, use the provided [docker-compose configuration](docker-compose.yml): ```bash -$ docker-compose build -$ docker-compose up +docker-compose build +docker-compose up # browse to http://localhost:8080 ``` @@ -63,11 +63,11 @@ host machine. Once they are: ```bash # Because files are copied from the container, we need to make them writable: -$ sudo chmod a+rw data/assets.json public/css/*.css +sudo chmod a+rw data/assets.json public/css/*.css # Now we can install dependencies and start watching for changes: -$ cd bootstrap -$ npm i -$ gulp +cd bootstrap +npm i +gulp ``` From there, any changes to CSS will be propagated to the application, and @@ -77,7 +77,7 @@ Alternately, you can use the following command to rebuild the base docker container: ```bash -$ docker-compose build php +docker-compose build php ``` ## Adding blog entries diff --git a/data/advisories/LP-2020-01.md b/data/advisories/LP-2020-01.md index 822cefa9..2ac73a65 100644 --- a/data/advisories/LP-2020-01.md +++ b/data/advisories/LP-2020-01.md @@ -4,7 +4,7 @@ title: "LP-2020-01: XSS vectors in laminas-api-tools/api-tools" date: '2020-04-01T16:30:00-05:00' --- -# LP-2020-01: XSS vectors in laminas-api-tools/api-tools +## LP-2020-01: XSS vectors in laminas-api-tools/api-tools The package [laminas-api-tools/api-tools](https://github.com/laminas-api-tools/api-tools) bundles a number of javascript assets for purposes of providing an diff --git a/data/advisories/LP-2020-02.md b/data/advisories/LP-2020-02.md index 1dd79c88..70683601 100644 --- a/data/advisories/LP-2020-02.md +++ b/data/advisories/LP-2020-02.md @@ -4,7 +4,7 @@ title: "LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documenta date: '2020-04-01T16:30:00-05:00' --- -# LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documentation-swagger +## LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documentation-swagger The package [laminas-api-tools/api-tools-documentation-swagger](https://github.com/laminas-api-tools/api-tools-documentation-swagger) bundles a number of javascript assets for purposes of providing API diff --git a/data/advisories/LP-2022-01.md b/data/advisories/LP-2022-01.md index 3870ea96..d47ecb0b 100644 --- a/data/advisories/LP-2022-01.md +++ b/data/advisories/LP-2022-01.md @@ -4,7 +4,7 @@ title: "LP-2022-01: Reflected XSS vectors in laminas/laminas-form" date: '2022-01-28T10:00:00-06:00' --- -# LP-2022-01: Reflected XSS vector in laminas/laminas-form +## LP-2022-01: Reflected XSS vector in laminas/laminas-form The package [laminas/laminas-form](https://github.com/laminas/laminas-form) contains a [laminas/laminas-view](https://docs.laminas.dev/laminas-view/) view helper for emitting form element, fieldset, and/or form validation errors, `formElementError()`. Validation messages can contain the original input, potentially resulting in a Reflected XSS vulnerability. diff --git a/data/advisories/LP-2022-02.md b/data/advisories/LP-2022-02.md index 6d8e5506..22ab902a 100644 --- a/data/advisories/LP-2022-02.md +++ b/data/advisories/LP-2022-02.md @@ -4,7 +4,7 @@ title: "LP-2022-02: HTTP Host Header Attack Vulnerabilities" date: '2022-07-25T15:35:00-06:00' --- -# LP-2022-02: HTTP Host Header Attack Vulnerabilities +## LP-2022-02: HTTP Host Header Attack Vulnerabilities The package [laminas/laminas-diactoros (Diactoros)](https://github.com/laminas/laminas-diactoros) is a [PSR-7 HTTP Message](https://www.php-fig.org/psr/psr-7/) and [PSR-17 HTTP Message Factory](https://www.php-fig.org/psr/psr-17/) implementation, providing HTTP request and response message representations both for making HTTP client requests and responding to HTTP requests server-side. When responding to an incoming request and generating a `ServerRequest` instance, the library takes into consideration a number of `X-Forwarded-*` headers when generating a `Uri` instance. diff --git a/data/advisories/LP-2023-01.md b/data/advisories/LP-2023-01.md index 7ee978ec..0ba2a6ab 100644 --- a/data/advisories/LP-2023-01.md +++ b/data/advisories/LP-2023-01.md @@ -4,7 +4,7 @@ title: "LP-2023-01: HTTP Multiline Header Termination Vulnerability" date: '2023-04-17T11:00:00-06:00' --- -# LP-2023-01: HTTP Multiline Header Termination Vulnerability +## LP-2023-01: HTTP Multiline Header Termination Vulnerability The package [laminas/laminas-diactoros (Diactoros)](https://github.com/laminas/laminas-diactoros) is a [PSR-7 HTTP Message](https://www.php-fig.org/psr/psr-7/) and [PSR-17 HTTP Message Factory](https://www.php-fig.org/psr/psr-17/) implementation, providing HTTP request and response message representations both for making HTTP client requests and responding to HTTP requests server-side. Affected versions of Diactoros accepted a single line feed (LF / `\n` ) character at the end of a header name. @@ -60,4 +60,3 @@ The Laminas Project thanks - [Graham Campbell](https://github.com/GrahamCampbell) for reporting the issue and coordinating release with other PSR-7 implementations. - [Tim Düsterhus](https://github.com/TimWolla) for developing and testing the patch used in Diactoros. - diff --git a/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md b/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md index b720ba98..07f4d5e8 100644 --- a/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md +++ b/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md @@ -7,7 +7,7 @@ public: true created: '2019-12-31T17:30:00-05:00' updated: '2020-01-13T13:30:00-05:00' tags: - - laminas + - laminas --- As the year and decade wrap up, we have some exciting news: we've just completed @@ -26,21 +26,21 @@ can find the code in the following locations: We still have a few things to iron out: -- The Packagist API, while it claimed to work and did not return errors, did not +- ~~The Packagist API, while it claimed to work and did not return errors, did not always abandon the old packages; we'll be auditing those later this - week. + week.~~ -- We will be renaming our Slack workspace later this week to reflect the - change. +- ~~We will be renaming our Slack workspace later this week to reflect the + change.~~ -- Likewise, we'll be renaming our Discourse and re-pointing it. +- ~~Likewise, we'll be renaming our Discourse and re-pointing it.~~ - Our bot will need some changes to work with the new repos, and we will likely be moving tasks such as building documentation to GitHub Actions. (Update: documentation is now built via GitHub Actions.) - We need to rebuild the former Apigility site to reflect the name change, and - plan to eventually push it to https://api-tools.getlaminas.org. + plan to eventually push it to [api-tools.getlaminas.org](https://api-tools.getlaminas.org). - We need to update the Zend Framework, Apigility, and Expressive websites to indicate the changes. @@ -73,7 +73,7 @@ To migrate a project, first install the laminas/laminas-migration package. Install the library globally using [Composer](https://getcomposer.org): ```bash -$ composer global require laminas/laminas-migration +composer global require laminas/laminas-migration ``` If you choose this option, you will need to ensure that the `vendor/bin/` @@ -83,7 +83,7 @@ subdirectory of your > global Composer installation is in your environment You can find where the global Composer installation is by executing: ```bash -$ composer global config home +composer global config home ``` On Linux and Mac operating systems, update your shell configuration to add @@ -110,14 +110,14 @@ that path to your `$PATH` environment variable. Clone the repository somewhere: ```bash -$ git clone https://github.com/laminas/laminas-migration.git +git clone https://github.com/laminas/laminas-migration.git ``` Install dependencies: ```bash -$ cd laminas-migration -$ composer install +cd laminas-migration +composer install ``` From there, either add the `bin/` directory to your `$PATH` (see the [note on @@ -127,11 +127,11 @@ alias to the `bin/laminas-migration` script using your shell: ```bash # Adding to PATH: -$ export PATH=/path/to/laminas-migration/bin:$PATH +export PATH=/path/to/laminas-migration/bin:$PATH # Symlinking to a directory in your PATH: -$ cd $HOME/bin && ln -s /path/to/laminas-migration/bin/laminas-migration . +cd $HOME/bin && ln -s /path/to/laminas-migration/bin/laminas-migration . # creating an alias: -$ alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration +alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration ``` ### 2. Run the migration command @@ -139,7 +139,7 @@ $ alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration From there, enter a project you wish to migrate, and run the following: ```bash -$ laminas-migration migrate +laminas-migration migrate ``` You may want to use the `--exclude` or `-e` option one or more times for @@ -147,7 +147,7 @@ directories to exclude from the rewrite; on the ZF website and my own, I used `-e data`, for instance: ```bash -$ laminas-migration migrate -e data +laminas-migration migrate -e data ``` > #### Module and Config Post Processor injection @@ -166,60 +166,60 @@ $ laminas-migration migrate -e data > to the `ConfigAggregator` constructor. The `ConfigAggregator` constructor > has the following signature: > -> ```php -> public function __construct( -> array $providers = [], -> ?string $cachedConfigFile = null, -> array $postProcessors = [] -> ) -> ``` +> ```php +> public function __construct( +> array $providers = [], +> ?string $cachedConfigFile = null, +> array $postProcessors = [] +> ) +> ``` > -> Typically, the structure of the `config/config.php` file in an Expressive -> application looks like the following: +> Typically, the structure of the `config/config.php` file in an Expressive +> application looks like the following: > -> ```php -> $cacheConfig = [ -> 'config_cache_path' => 'data/cache/app_config.php', -> ]; +> ```php +> $cacheConfig = [ +> 'config_cache_path' => 'data/cache/app_config.php', +> ]; > -> $aggregator = new ConfigAggregator([ -> // config providers from 3rd party code -> // ... +> $aggregator = new ConfigAggregator([ +> // config providers from 3rd party code +> // ... > -> // App-specific modules -> // ... +> // App-specific modules +> // ... > -> // Include cache configuration -> new ArrayProvider($cacheConfig), +> // Include cache configuration +> new ArrayProvider($cacheConfig), > -> // Load application config in a pre-defined order in such a way that local settings -> // overwrite global settings. (Loaded as first to last): -> // - `global.php` -> // - `*.global.php` -> // - `local.php` -> // - `*.local.php` -> new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), +> // Load application config in a pre-defined order in such a way that local settings +> // overwrite global settings. (Loaded as first to last): +> // - `global.php` +> // - `*.global.php` +> // - `local.php` +> // - `*.local.php` +> new PhpFileProvider('config/autoload/{{,*.}global,{,*.}local}.php'), > -> // Load development config if it exists -> new PhpFileProvider('config/development.config.php'), -> ], $cacheConfig['config_cache_path']); +> // Load development config if it exists +> new PhpFileProvider('config/development.config.php'), +> ], $cacheConfig['config_cache_path']); > -> return $aggregator->getMergedConfig(); -> ``` +> return $aggregator->getMergedConfig(); +> ``` > -> As such, the migration tooling rewrites the second to last line to read: +> As such, the migration tooling rewrites the second to last line to read: > -> ```php -> ], $cacheConfig['config_cache_path'], [\Laminas\ZendFrameworkBridge\ConfigPostProcessor::class]); -> ``` +> ```php +> ], $cacheConfig['config_cache_path'], [\Laminas\ZendFrameworkBridge\ConfigPostProcessor::class]); +> ``` > -> In most cases, failure to inject means that the individual arguments have -> been pushed to their own line. In such cases, add the third argument as -> detailed above. +> In most cases, failure to inject means that the individual arguments have +> been pushed to their own line. In such cases, add the third argument as +> detailed above. > -> In other cases, applications may already be using post processors. If so, -> add `\Laminas\ZendFrameworkBridge\ConfigPostProcessor::class` to the list of -> post processors. +> In other cases, applications may already be using post processors. If so, +> add `\Laminas\ZendFrameworkBridge\ConfigPostProcessor::class` to the list of +> post processors. ### 3. Install dependencies @@ -227,7 +227,7 @@ Once migration is done and you've added the repository, you can install dependencies: ```bash -$ composer install +composer install ``` From there, run tests, and report any issues to the [Laminas diff --git a/data/blog/2020/2020-03-09-transferring-zf-to-laminas.md b/data/blog/2020/2020-03-09-transferring-zf-to-laminas.md index 5d3ea06b..a961ec43 100644 --- a/data/blog/2020/2020-03-09-transferring-zf-to-laminas.md +++ b/data/blog/2020/2020-03-09-transferring-zf-to-laminas.md @@ -7,9 +7,9 @@ public: true created: '2020-03-09T11:05:00-05:00' updated: '2020-03-09T11:05:00-05:00' tags: - - laminas - - transfer - - zend-framework + - laminas + - transfer + - zend-framework --- Back in October 2018, Rogue Wave Software @@ -75,8 +75,7 @@ As such, we now have the following GitHub organisations representing the Laminas Project: - [laminas](https://github.com/laminas), representing components and the MVC. -- [laminas-api-tools](https://github.com/laminas-api-tools), representing the - Laminas API Tools components (formerly Apigility). +- [laminas-api-tools](https://github.com/laminas-api-tools), representing the Laminas API Tools components (formerly Apigility). - [mezzio](https://github.com/mezzio), representing the Mezzio middleware runtime and components (formerly Expressive). @@ -115,7 +114,7 @@ components. Hard as the decision was, we also decided to abandon some packages. These include: -- [`ZendService\Amazon`](https://github.com/zendframework/ZendService_Amazon): +- [`ZendService\Amazon`](https://github.com/zendframework/ZendService_Amazon): we suggest using the official [AWS PHP SDK](https://github.com/aws/aws-sdk-php) - [`ZendService\Google\Gcm`](https://github.com/zendframework/ZendService_Google_Gcm) @@ -173,11 +172,11 @@ interface MyInterface } ``` - We wanted to ensure code such as this works when the Laminas component - replacing the ZF component is installed. To accomplish this, we created an - [additional autoloader](https://github.com/laminas/laminas-zendframework-bridge/blob/master/src/Autoloader.php#L111-L155), - that creates a `class_alias` of the legacy class to the Laminas equivalent - any time a Laminas class is autoloaded. +We wanted to ensure code such as this works when the Laminas component +replacing the ZF component is installed. To accomplish this, we created an +[additional autoloader](https://github.com/laminas/laminas-zendframework-bridge/blob/master/src/Autoloader.php#L111-L155), +that creates a `class_alias` of the legacy class to the Laminas equivalent +any time a Laminas class is autoloaded. There was also additional difficulty: we had some integration classes with "Zend" in the name (see for example [`LaminasRouter`](https://github.com/mezzio/mezzio-laminasrouter/blob/master/src/LaminasRouter.php#L38)). @@ -203,10 +202,10 @@ For a more complete examples: - The rewritten [`create_uploaded_file.php`](https://github.com/laminas/laminas-diactoros/blob/master/src/functions/create_uploaded_file.php) - Its legacy -[`create_uploaded_file.legacy.php`](https://github.com/laminas/laminas-diactoros/blob/master/src/functions/create_uploaded_file.legacy.php) file, + [`create_uploaded_file.legacy.php`](https://github.com/laminas/laminas-diactoros/blob/master/src/functions/create_uploaded_file.legacy.php) file, - And an updated [`composer.json`](https://github.com/laminas/laminas-diactoros/blob/master/composer.json#L53-L70). -> See the transfer tool code: [FunctionAliasFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/FunctionAliasFixture.php). +> See the transfer tool code: [FunctionAliasFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/FunctionAliasFixture.php). ### Custom constants @@ -281,7 +280,7 @@ rewritten. > If a library provides a delegator for `\Zend\ClassName` but you are using > `\Laminas\ClassName`, the legacy delegator will not be triggered. You will need > to update your own configuration to add it. - +> > See the transfer tool code: [DIAliasFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/DIAliasFixture.php). ### Plugin Managers @@ -303,7 +302,7 @@ For an example, you can inspect the additional aliases in the > changed from their first introduction to their latest release, particularly as > they were updated to target the version 3 release of our service manager. Our > tool had to accommodate these changes! - +> > See the transfer tool code: [PluginManagerFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/PluginManagerFixture.php). ### Factories @@ -389,7 +388,7 @@ to see how complicated it got! While we don't like nesting ternaries, in many cases, it was the most consistent way to accomplish our ends. -> See the transfer tool code: [LegacyFactoriesFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/LegacyFactoriesFixture.php). +> See the transfer tool code: [LegacyFactoriesFixture](https://github.com/michalbundyra/laminas-transfer/blob/master/src/Fixture/LegacyFactoriesFixture.php). ### Configuration keys - config postprocessor and configuration merge listener @@ -744,7 +743,7 @@ The first and most serious issue was with [namespaced function](#custom-function We somehow missed including a "return" statement in the legacy functions when calling then new variants. -Because of that we had to issue patch versions for: +Because of that we had to issue patch versions for: - [laminas-diactoros](https://github.com/laminas/laminas-diactoros), - [laminas-stratigility](https://github.com/laminas/laminas-stratigility), diff --git a/data/blog/2024/2024-07-02-dotkernel-a-replacement-for-laminas-api-tools.md b/data/blog/2024/2024-07-02-dotkernel-a-replacement-for-laminas-api-tools.md index e5047d16..a0b8e32f 100644 --- a/data/blog/2024/2024-07-02-dotkernel-a-replacement-for-laminas-api-tools.md +++ b/data/blog/2024/2024-07-02-dotkernel-a-replacement-for-laminas-api-tools.md @@ -28,7 +28,7 @@ as `security-only`, primarily because the resources to continue the project were [Extended discussion about Laminas Api Tools retirement](https://github.com/laminas/technical-steering-committee/blob/main/meetings/minutes/2023-01-09-TSC-Minutes.md) -### How to move forward? Choose Dotkernel API! +### How to move forward? Choose Dotkernel API The TSC recommendation as a replacement for current Laminas API Tools is [Dotkernel API](https://www.dotkernel.org/), mostly because it is built on top of Mezzio and uses Laminas components. @@ -81,4 +81,3 @@ fast, reliable solution for any project, from entry-level to enterprise. - Documentation for the API and all components and libraries: [docs.dotkernel.org](https://docs.dotkernel.org/). [You can find the minutes in the TSC repository.](https://github.com/laminas/technical-steering-committee/blob/main/meetings/minutes/2024-05-06-TSC-Minutes.md) - diff --git a/data/blog/2024/2024-07-29-current-maintenance-status-of-laminas-mezzio-packages.md b/data/blog/2024/2024-07-29-current-maintenance-status-of-laminas-mezzio-packages.md index 86449635..6eb37e3e 100644 --- a/data/blog/2024/2024-07-29-current-maintenance-status-of-laminas-mezzio-packages.md +++ b/data/blog/2024/2024-07-29-current-maintenance-status-of-laminas-mezzio-packages.md @@ -7,7 +7,7 @@ public: true created: '2024-07-29T11:00:00-01:00' updated: '2024-07-29T11:00:00-01:00' tags: - - maintenance status + - maintenance status --- The Laminas Project has created a large number of packages to serve the needs of the PHP community. diff --git a/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md b/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md index ab123a82..f9a69a76 100644 --- a/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md +++ b/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md @@ -1,5 +1,5 @@ --- -id: 2024-08-05-using-laminas-continuous-integration +id: 2024-08-05-using-laminas-continuous-integration.md author: julian title: 'Using Laminas Continuous Integration' draft: false @@ -103,14 +103,14 @@ It usually takes less than a minute to receive the feedback that turns iterating Its high value is guaranteed by the authors of the Mezzio microframework and Laminas components, the people who best understand the ins and outs of those code bases. They expanded their initial CI workflow multiple times, based on their needs, while ensuring that the flow has universal application for any PHP project. -- **The CI pipeline can be optimized for PHP-specific tasks** because Laminas is designed specifically for PHP applications. +- **The CI pipeline can be optimized for PHP-specific tasks** because Laminas is designed specifically for PHP applications. The tasks range from dependency management with Composer, to code style checks, to running PHPUnit tests. - Seamless integration with GitHub Actions - **Composer integration** ensures consistent dependency management across different environments, from development to production, which is crucial for maintaining stability and reliability. - Laminas encourages **modern PHP practices** by enforcing PSR (PHP Standard Recommendation) compliance and the use of dependency injection. - Extensive **Documentation and Community Support** -### More on the topic: +### More on the topic - [Blog post by Matthew Weier O'Phinney: "Laminas CI Automation"](https://mwop.net/blog/2021-03-12-laminas-ci.html) - [Repository of Laminas Continuous Integration Action on GitHub](https://github.com/laminas/laminas-continuous-integration-action) diff --git a/data/blog/2024/2024-09-26-using-laminas-continuous-delivery-and-deployment.md b/data/blog/2024/2024-09-26-using-laminas-continuous-delivery-and-deployment.md index cdeb6e0c..de064b92 100644 --- a/data/blog/2024/2024-09-26-using-laminas-continuous-delivery-and-deployment.md +++ b/data/blog/2024/2024-09-26-using-laminas-continuous-delivery-and-deployment.md @@ -61,4 +61,4 @@ Maintainers are able to add contributions easier and post more reliable releases New contributors have a smoother onboarding, given the well-defined steps that help both the open source scene and private projects. Read more about [Laminas Continuous Integration GitHub Action](https://github.com/laminas/laminas-continuous-integration-action) and [how to set up GitHub Actions](https://docs.github.com/en/actions). -Learn more about [Creating a CI matrix for use in a GitHub Action](https://github.com/laminas/laminas-ci-matrix-action). \ No newline at end of file +Learn more about [Creating a CI matrix for use in a GitHub Action](https://github.com/laminas/laminas-ci-matrix-action). diff --git a/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md b/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md index 9914f33b..4f388e90 100644 --- a/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md +++ b/data/blog/2024/2024-10-25-summary-of-the-meeting-in-october-2024.md @@ -45,4 +45,4 @@ This allows for a longer evaluation period to ensure that quality reviews and fe Both items on the agenda were discussed in detail, and many relevant points of view were considered. These items mark a new direction and bringing a new developer on board, so the ultimate decisions must not be taken lightly. -Both have been greenlit, at first with small steps to allow careful evaluation and further discussion in future TSC meetings. \ No newline at end of file +Both have been greenlit, at first with small steps to allow careful evaluation and further discussion in future TSC meetings. From a913a188872486b94c8f674789225a97635d51c9 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Thu, 28 Nov 2024 12:42:12 +0200 Subject: [PATCH 24/38] linting fix Signed-off-by: Jurj-Bogdan --- data/blog/2020-04-07-tsc-meeting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/blog/2020-04-07-tsc-meeting.md b/data/blog/2020-04-07-tsc-meeting.md index c3b4a045..6211b0f5 100644 --- a/data/blog/2020-04-07-tsc-meeting.md +++ b/data/blog/2020-04-07-tsc-meeting.md @@ -20,7 +20,7 @@ A brief summary of decisions follows. -- The TSC voted to accept four new members to the committee: +- The TSC voted to accept four new members to the committee: [Abdul Malik Ikhsan (@samsonasik)](https://github.com/samsonasik), [Luís Cobucci (@lcobucci)](https://github.com/lcobucci), [Maximilian Bösing (@boesing)](https://github.com/boesing), and From 4a7c3f3a81881f3e34f1facb25b3af9b792b8ea4 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Thu, 28 Nov 2024 13:58:40 +0200 Subject: [PATCH 25/38] reverted first headlines && minor config change Signed-off-by: Jurj-Bogdan --- .markdownlint.json | 5 ++++- data/advisories/LP-2020-01.md | 2 +- data/advisories/LP-2020-02.md | 2 +- data/advisories/LP-2022-01.md | 2 +- data/advisories/LP-2022-02.md | 2 +- data/advisories/LP-2023-01.md | 2 +- .../2024/2024-08-05-using-laminas-continuous-integration.md | 2 +- 7 files changed, 10 insertions(+), 7 deletions(-) diff --git a/.markdownlint.json b/.markdownlint.json index 3cbcbe14..f7650f50 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,4 +1,7 @@ { "default": true, - "MD013": false + "MD013": false, + "MD025": { + "front_matter_title": "" + } } \ No newline at end of file diff --git a/data/advisories/LP-2020-01.md b/data/advisories/LP-2020-01.md index 2ac73a65..822cefa9 100644 --- a/data/advisories/LP-2020-01.md +++ b/data/advisories/LP-2020-01.md @@ -4,7 +4,7 @@ title: "LP-2020-01: XSS vectors in laminas-api-tools/api-tools" date: '2020-04-01T16:30:00-05:00' --- -## LP-2020-01: XSS vectors in laminas-api-tools/api-tools +# LP-2020-01: XSS vectors in laminas-api-tools/api-tools The package [laminas-api-tools/api-tools](https://github.com/laminas-api-tools/api-tools) bundles a number of javascript assets for purposes of providing an diff --git a/data/advisories/LP-2020-02.md b/data/advisories/LP-2020-02.md index 70683601..1dd79c88 100644 --- a/data/advisories/LP-2020-02.md +++ b/data/advisories/LP-2020-02.md @@ -4,7 +4,7 @@ title: "LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documenta date: '2020-04-01T16:30:00-05:00' --- -## LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documentation-swagger +# LP-2020-02: XSS and RCE vectors in laminas-api-tools/api-tools-documentation-swagger The package [laminas-api-tools/api-tools-documentation-swagger](https://github.com/laminas-api-tools/api-tools-documentation-swagger) bundles a number of javascript assets for purposes of providing API diff --git a/data/advisories/LP-2022-01.md b/data/advisories/LP-2022-01.md index d47ecb0b..3870ea96 100644 --- a/data/advisories/LP-2022-01.md +++ b/data/advisories/LP-2022-01.md @@ -4,7 +4,7 @@ title: "LP-2022-01: Reflected XSS vectors in laminas/laminas-form" date: '2022-01-28T10:00:00-06:00' --- -## LP-2022-01: Reflected XSS vector in laminas/laminas-form +# LP-2022-01: Reflected XSS vector in laminas/laminas-form The package [laminas/laminas-form](https://github.com/laminas/laminas-form) contains a [laminas/laminas-view](https://docs.laminas.dev/laminas-view/) view helper for emitting form element, fieldset, and/or form validation errors, `formElementError()`. Validation messages can contain the original input, potentially resulting in a Reflected XSS vulnerability. diff --git a/data/advisories/LP-2022-02.md b/data/advisories/LP-2022-02.md index 22ab902a..6d8e5506 100644 --- a/data/advisories/LP-2022-02.md +++ b/data/advisories/LP-2022-02.md @@ -4,7 +4,7 @@ title: "LP-2022-02: HTTP Host Header Attack Vulnerabilities" date: '2022-07-25T15:35:00-06:00' --- -## LP-2022-02: HTTP Host Header Attack Vulnerabilities +# LP-2022-02: HTTP Host Header Attack Vulnerabilities The package [laminas/laminas-diactoros (Diactoros)](https://github.com/laminas/laminas-diactoros) is a [PSR-7 HTTP Message](https://www.php-fig.org/psr/psr-7/) and [PSR-17 HTTP Message Factory](https://www.php-fig.org/psr/psr-17/) implementation, providing HTTP request and response message representations both for making HTTP client requests and responding to HTTP requests server-side. When responding to an incoming request and generating a `ServerRequest` instance, the library takes into consideration a number of `X-Forwarded-*` headers when generating a `Uri` instance. diff --git a/data/advisories/LP-2023-01.md b/data/advisories/LP-2023-01.md index 0ba2a6ab..750893b2 100644 --- a/data/advisories/LP-2023-01.md +++ b/data/advisories/LP-2023-01.md @@ -4,7 +4,7 @@ title: "LP-2023-01: HTTP Multiline Header Termination Vulnerability" date: '2023-04-17T11:00:00-06:00' --- -## LP-2023-01: HTTP Multiline Header Termination Vulnerability +# LP-2023-01: HTTP Multiline Header Termination Vulnerability The package [laminas/laminas-diactoros (Diactoros)](https://github.com/laminas/laminas-diactoros) is a [PSR-7 HTTP Message](https://www.php-fig.org/psr/psr-7/) and [PSR-17 HTTP Message Factory](https://www.php-fig.org/psr/psr-17/) implementation, providing HTTP request and response message representations both for making HTTP client requests and responding to HTTP requests server-side. Affected versions of Diactoros accepted a single line feed (LF / `\n` ) character at the end of a header name. diff --git a/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md b/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md index f9a69a76..a742b50f 100644 --- a/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md +++ b/data/blog/2024/2024-08-05-using-laminas-continuous-integration.md @@ -1,5 +1,5 @@ --- -id: 2024-08-05-using-laminas-continuous-integration.md +id: 2024-08-05-using-laminas-continuous-integration author: julian title: 'Using Laminas Continuous Integration' draft: false From bf0f179bd2baab8239aee4c6371a0f0eaf83fca3 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Fri, 29 Nov 2024 16:02:47 +0200 Subject: [PATCH 26/38] laminas-ci linting rules Signed-off-by: Jurj-Bogdan --- .markdownlint.json | 12 ++++++++---- ADD_BLOG_ENTRY.md | 6 +++--- COPYRIGHT.md | 2 +- data/advisories/LP-2020-01.md | 6 +++--- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/.markdownlint.json b/.markdownlint.json index f7650f50..b73a25b9 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -1,7 +1,11 @@ { "default": true, + "MD007": { "indent": 4 }, "MD013": false, - "MD025": { - "front_matter_title": "" - } -} \ No newline at end of file + "MD014": false, + "MD024": false, + "MD025": { "front_matter_title": "" }, + "MD028": false, + "MD031": { "list_items": false }, + "MD034": false +} diff --git a/ADD_BLOG_ENTRY.md b/ADD_BLOG_ENTRY.md index afad4f01..eaffb7b6 100644 --- a/ADD_BLOG_ENTRY.md +++ b/ADD_BLOG_ENTRY.md @@ -4,9 +4,9 @@ Blog entries can be added by following these steps: - If submitting for the first time, an [author](#blog-author) YAML file must be added to the `data/blog/authors` directory. - Add an MD file containing the [blog post's metadata and body](#blog-post-content). - - blog post files are named following a `yyyy-mm-dd-title` convention, e.g., `2024-10-24-blog-title.md` - - each file must be added to the appropriate year's directory, found in `data/blog/` - - use the following command to make sure your submission will be correctly built: + - blog post files are named following a `yyyy-mm-dd-title` convention, e.g., `2024-10-24-blog-title.md` + - each file must be added to the appropriate year's directory, found in `data/blog/` + - use the following command to make sure your submission will be correctly built: ```bash composer build-blog diff --git a/COPYRIGHT.md b/COPYRIGHT.md index 7a65a906..d2f14c03 100644 --- a/COPYRIGHT.md +++ b/COPYRIGHT.md @@ -1 +1 @@ -# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. () +# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/data/advisories/LP-2020-01.md b/data/advisories/LP-2020-01.md index 822cefa9..44a0932d 100644 --- a/data/advisories/LP-2020-01.md +++ b/data/advisories/LP-2020-01.md @@ -12,10 +12,10 @@ adminstration GUI and/or landing page. Some of these assets had reported XSS (cross-site scripting) vulnerabilities: - Bootstrap: - - [CVE-2018-14042](https://nvd.nist.gov/vuln/detail/CVE-2018-14042) - - [CVE-2019-8331](https://nvd.nist.gov/vuln/detail/CVE-2019-8331) + - [CVE-2018-14042](https://nvd.nist.gov/vuln/detail/CVE-2018-14042) + - [CVE-2019-8331](https://nvd.nist.gov/vuln/detail/CVE-2019-8331) - jQuery: - - [CVE-2015-9251](https://nvd.nist.gov/vuln/detail/CVE-2015-9251) + - [CVE-2015-9251](https://nvd.nist.gov/vuln/detail/CVE-2015-9251) ## Affected versions From 16cfffcd5a16e271b0232d43ed7beb20e9382498 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 3 Dec 2024 10:12:50 +0200 Subject: [PATCH 27/38] md014 fix & excluded files Signed-off-by: Jurj-Bogdan --- .github/workflows/markdown-linting.yml | 2 ++ ADD_BLOG_ENTRY.md | 2 +- COPYRIGHT.md | 2 +- LICENSE.md | 2 +- README.md | 24 +++++++++---------- ...-12-31-out-with-the-old-in-with-the-new.md | 24 +++++++++---------- 6 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.github/workflows/markdown-linting.yml b/.github/workflows/markdown-linting.yml index eefc2a6b..32994af6 100644 --- a/.github/workflows/markdown-linting.yml +++ b/.github/workflows/markdown-linting.yml @@ -17,5 +17,7 @@ jobs: globs: | **/*.md !README.md + !LICENSE.md + !COPYRIGHT.md !bootstrap !public diff --git a/ADD_BLOG_ENTRY.md b/ADD_BLOG_ENTRY.md index eaffb7b6..ed6eb0e1 100644 --- a/ADD_BLOG_ENTRY.md +++ b/ADD_BLOG_ENTRY.md @@ -9,7 +9,7 @@ Blog entries can be added by following these steps: - use the following command to make sure your submission will be correctly built: ```bash -composer build-blog +$ composer build-blog ``` - When ready, submit the blog post for review via pull request to the default branch. diff --git a/COPYRIGHT.md b/COPYRIGHT.md index d2f14c03..0a8cccc0 100644 --- a/COPYRIGHT.md +++ b/COPYRIGHT.md @@ -1 +1 @@ -# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) +Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/LICENSE.md b/LICENSE.md index 20931766..835da237 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC +Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 2a2cd498..9e0d37c2 100644 --- a/README.md +++ b/README.md @@ -30,28 +30,28 @@ RELEASE_FEED_TOKEN=aaaabbbbccccddddeeeeffffgggg0000 Second, install dependencies: ```bash -composer install +$ composer install ``` Third, put the application in development mode: ```bash -./vendor/bin/laminas-development-mode enable +$ ./vendor/bin/laminas-development-mode enable ``` Fourth, prepare the blog and security announcements: ```bash -mkdir -p var/blog/feeds -mkdir -p public/js -composer build +$ mkdir -p var/blog/feeds +$ mkdir -p public/js +$ composer build ``` Finally, use the provided [docker-compose configuration](docker-compose.yml): ```bash -docker-compose build -docker-compose up +$ docker-compose build +$ docker-compose up # browse to http://localhost:8080 ``` @@ -63,11 +63,11 @@ host machine. Once they are: ```bash # Because files are copied from the container, we need to make them writable: -sudo chmod a+rw data/assets.json public/css/*.css +$ sudo chmod a+rw data/assets.json public/css/*.css # Now we can install dependencies and start watching for changes: -cd bootstrap -npm i -gulp +$ cd bootstrap +$ npm i +$ gulp ``` From there, any changes to CSS will be propagated to the application, and @@ -77,7 +77,7 @@ Alternately, you can use the following command to rebuild the base docker container: ```bash -docker-compose build php +$ docker-compose build php ``` ## Adding blog entries diff --git a/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md b/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md index 07f4d5e8..85971dea 100644 --- a/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md +++ b/data/blog/2019/2019-12-31-out-with-the-old-in-with-the-new.md @@ -73,7 +73,7 @@ To migrate a project, first install the laminas/laminas-migration package. Install the library globally using [Composer](https://getcomposer.org): ```bash -composer global require laminas/laminas-migration +$ composer global require laminas/laminas-migration ``` If you choose this option, you will need to ensure that the `vendor/bin/` @@ -83,7 +83,7 @@ subdirectory of your > global Composer installation is in your environment You can find where the global Composer installation is by executing: ```bash -composer global config home +$ composer global config home ``` On Linux and Mac operating systems, update your shell configuration to add @@ -99,7 +99,7 @@ that path to your `$PATH` environment variable. > `$HOME/.zshrc`, `$HOME/.profile`, etc.): > > ```bash -> export PATH={path to add}:$PATH +> $ export PATH={path to add}:$PATH > ``` > > For Windows, the situation is a bit more involved; [this HOWTO](https://www.architectryan.com/2018/03/17/add-to-the-path-on-windows-10/) @@ -110,14 +110,14 @@ that path to your `$PATH` environment variable. Clone the repository somewhere: ```bash -git clone https://github.com/laminas/laminas-migration.git +$ git clone https://github.com/laminas/laminas-migration.git ``` Install dependencies: ```bash -cd laminas-migration -composer install +$ cd laminas-migration +$ composer install ``` From there, either add the `bin/` directory to your `$PATH` (see the [note on @@ -127,11 +127,11 @@ alias to the `bin/laminas-migration` script using your shell: ```bash # Adding to PATH: -export PATH=/path/to/laminas-migration/bin:$PATH +$ export PATH=/path/to/laminas-migration/bin:$PATH # Symlinking to a directory in your PATH: -cd $HOME/bin && ln -s /path/to/laminas-migration/bin/laminas-migration . +$ cd $HOME/bin && ln -s /path/to/laminas-migration/bin/laminas-migration . # creating an alias: -alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration +$ alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration ``` ### 2. Run the migration command @@ -139,7 +139,7 @@ alias laminas-migration=/path/to/laminas-migration/bin/laminas-migration From there, enter a project you wish to migrate, and run the following: ```bash -laminas-migration migrate +$ laminas-migration migrate ``` You may want to use the `--exclude` or `-e` option one or more times for @@ -147,7 +147,7 @@ directories to exclude from the rewrite; on the ZF website and my own, I used `-e data`, for instance: ```bash -laminas-migration migrate -e data +$ laminas-migration migrate -e data ``` > #### Module and Config Post Processor injection @@ -227,7 +227,7 @@ Once migration is done and you've added the repository, you can install dependencies: ```bash -composer install +$ composer install ``` From there, run tests, and report any issues to the [Laminas From 9aa4e5ba5c9689def2ab8c213d81cb9a5e894926 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:22:16 +0000 Subject: [PATCH 28/38] Update Laminas packages (#234) | datasource | package | from | to | | ---------- | ----------------------------------- | ------ | ------ | | packagist | laminas/laminas-cli | 1.10.0 | 1.11.0 | | packagist | laminas/laminas-component-installer | 3.4.0 | 3.5.0 | Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- composer.json | 4 +-- composer.lock | 76 ++++++++++++++++++++++++++------------------------- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/composer.json b/composer.json index e814c62c..f37e1f1b 100644 --- a/composer.json +++ b/composer.json @@ -38,8 +38,8 @@ "ext-curl": "*", "ext-pdo": "*", "dflydev/fig-cookies": "^3.1.0", - "laminas/laminas-cli": "^1.10.0", - "laminas/laminas-component-installer": "^3.4.0", + "laminas/laminas-cli": "^1.11.0", + "laminas/laminas-component-installer": "^3.5.0", "laminas/laminas-config-aggregator": "^1.17.0", "laminas/laminas-diactoros": "^3.5.0", "laminas/laminas-feed": "^2.23.0", diff --git a/composer.lock b/composer.lock index dde6c4cc..efb8175e 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": "ac6807ea565135dacd76f0773debfd33", + "content-hash": "1ed74b4fb82d276ddf9c7aa5b58a3dbb", "packages": [ { "name": "brick/varexporter", @@ -250,35 +250,37 @@ }, { "name": "laminas/laminas-cli", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-cli.git", - "reference": "cc59875b2a983b05a70abf4f9b3af739b1257f34" + "reference": "159b48f896fb2502cb6618a95307b56a0f23e592" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-cli/zipball/cc59875b2a983b05a70abf4f9b3af739b1257f34", - "reference": "cc59875b2a983b05a70abf4f9b3af739b1257f34", + "url": "https://api.github.com/repos/laminas/laminas-cli/zipball/159b48f896fb2502cb6618a95307b56a0f23e592", + "reference": "159b48f896fb2502cb6618a95307b56a0f23e592", "shasum": "" }, "require": { "composer-runtime-api": "^2.0.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "psr/container": "^1.0 || ^2.0", "symfony/console": "^6.0 || ^7.0", "symfony/event-dispatcher": "^6.0 || ^7.0", - "symfony/polyfill-php80": "^1.17", "webmozart/assert": "^1.10" }, + "conflict": { + "amphp/amp": "<2.6.4" + }, "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "laminas/laminas-mvc": "^3.7.0", - "laminas/laminas-servicemanager": "^3.22.1", + "laminas/laminas-coding-standard": "^3.0.1", + "laminas/laminas-mvc": "^3.8.0", + "laminas/laminas-servicemanager": "^3.23.0", "mikey179/vfsstream": "2.0.x-dev", - "phpunit/phpunit": "^10.5.5", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.18" + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.26.1" }, "bin": [ "bin/laminas" @@ -314,36 +316,36 @@ "type": "community_bridge" } ], - "time": "2024-01-02T15:08:03+00:00" + "time": "2024-11-22T12:39:15+00:00" }, { "name": "laminas/laminas-component-installer", - "version": "3.4.0", + "version": "3.5.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-component-installer.git", - "reference": "e4c15d50c5dcbe0207285659f083df70bb256bb6" + "reference": "8752d73b5df8c368ec0bf2aff2b32e00e0ac8b1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-component-installer/zipball/e4c15d50c5dcbe0207285659f083df70bb256bb6", - "reference": "e4c15d50c5dcbe0207285659f083df70bb256bb6", + "url": "https://api.github.com/repos/laminas/laminas-component-installer/zipball/8752d73b5df8c368ec0bf2aff2b32e00e0ac8b1b", + "reference": "8752d73b5df8c368ec0bf2aff2b32e00e0ac8b1b", "shasum": "" }, "require": { "composer-plugin-api": "^2.0", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { "zendframework/zend-component-installer": "*" }, "require-dev": { - "composer/composer": "^2.6.4", - "laminas/laminas-coding-standard": "~2.5.0", + "composer/composer": "^2.7.7", + "laminas/laminas-coding-standard": "~3.0.0", "mikey179/vfsstream": "^1.6.11", - "phpunit/phpunit": "^10.4", - "psalm/plugin-phpunit": "^0.18.0", - "vimeo/psalm": "^5.15.0", + "phpunit/phpunit": "^10.5.35", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.24.0", "webmozart/assert": "^1.11.0" }, "type": "composer-plugin", @@ -381,7 +383,7 @@ "type": "community_bridge" } ], - "time": "2023-11-21T15:32:55+00:00" + "time": "2024-11-26T14:11:43+00:00" }, { "name": "laminas/laminas-config-aggregator", @@ -2996,16 +2998,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "87254c78dd50721cfd015b62277a8281c5589702" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87254c78dd50721cfd015b62277a8281c5589702", - "reference": "87254c78dd50721cfd015b62277a8281c5589702", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { @@ -3056,7 +3058,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.1.6" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -3072,20 +3074,20 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -3132,7 +3134,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -3148,7 +3150,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/polyfill-ctype", From c3129188e225135100490d00f3086ee7623e2993 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 10:47:06 +0000 Subject: [PATCH 29/38] Lock file maintenance (#235) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 36 +++---- composer.lock | 197 +++++++++++++++++++----------------- 2 files changed, 120 insertions(+), 113 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index b1f83d61..4b8c5048 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -881,9 +881,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001680", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz", - "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", + "version": "1.0.30001686", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", + "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", "dev": true, "funding": [ { @@ -1243,9 +1243,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.62", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.62.tgz", - "integrity": "sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==", + "version": "1.5.68", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz", + "integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==", "dev": true, "license": "ISC" }, @@ -2188,9 +2188,9 @@ } }, "node_modules/immutable": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.2.tgz", - "integrity": "sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", "dev": true, "license": "MIT" }, @@ -2599,9 +2599,9 @@ } }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.8", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", "dev": true, "funding": [ { @@ -3158,9 +3158,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.81.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.81.0.tgz", - "integrity": "sha512-Q4fOxRfhmv3sqCLoGfvrC9pRV8btc0UtqL9mN6Yrv6Qi9ScL55CVH1vlPP863ISLEEMNLLuu9P+enCeGHlnzhA==", + "version": "1.81.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.81.1.tgz", + "integrity": "sha512-VNLgf4FC5yFyKwAumAAwwNh8X4SevlVREq3Y8aDZIkm0lI/zO1feycMXQ4hn+eB6FVhRbleSQ1Yb/q8juSldTA==", "dev": true, "license": "MIT", "dependencies": { @@ -3837,9 +3837,9 @@ } }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, "license": "ISC", "bin": { diff --git a/composer.lock b/composer.lock index efb8175e..54198ed4 100644 --- a/composer.lock +++ b/composer.lock @@ -2228,26 +2228,26 @@ }, { "name": "phly/phly-configfactory", - "version": "1.3.0", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/phly/phly-configfactory.git", - "reference": "a5fbc17fde702013876da874c1e9089f95f26d58" + "reference": "d9680120a3f3e9b6f9e71b6bf2f97a7eabe5127f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phly/phly-configfactory/zipball/a5fbc17fde702013876da874c1e9089f95f26d58", - "reference": "a5fbc17fde702013876da874c1e9089f95f26d58", + "url": "https://api.github.com/repos/phly/phly-configfactory/zipball/d9680120a3f3e9b6f9e71b6bf2f97a7eabe5127f", + "reference": "d9680120a3f3e9b6f9e71b6bf2f97a7eabe5127f", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "psr/container": "^1.0 || ^2.0" }, "require-dev": { "laminas/laminas-coding-standard": "~2.3.0", "laminas/laminas-servicemanager": "^3.4", - "phpunit/phpunit": "^9.6" + "phpunit/phpunit": "^10.5" }, "suggest": { "laminas/laminas-servicemanager": "Install laminas-servicemanager to use the ConfigAbstractFactory" @@ -2274,24 +2274,24 @@ "rss": "https://github.com/phly/phly-configfactory/releases.atom", "source": "https://github.com/phly/phly-configfactory" }, - "time": "2024-04-17T13:58:43+00:00" + "time": "2024-11-25T20:58:25+00:00" }, { "name": "phly/phly-event-dispatcher", - "version": "1.4.0", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/phly/phly-event-dispatcher.git", - "reference": "c0f8043da05aeeaf95865b0f380028727a1b6cac" + "reference": "0a1b0aa21ace0f6f6736db71cdd3a3580fd9f481" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phly/phly-event-dispatcher/zipball/c0f8043da05aeeaf95865b0f380028727a1b6cac", - "reference": "c0f8043da05aeeaf95865b0f380028727a1b6cac", + "url": "https://api.github.com/repos/phly/phly-event-dispatcher/zipball/0a1b0aa21ace0f6f6736db71cdd3a3580fd9f481", + "reference": "0a1b0aa21ace0f6f6736db71cdd3a3580fd9f481", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", "psr/container": "^1.0 || ^2.0", "psr/event-dispatcher": "^1.0" }, @@ -2304,7 +2304,7 @@ "require-dev": { "fig/event-dispatcher-util": "^1.0", "laminas/laminas-coding-standard": "~2.3.0", - "phpunit/phpunit": "^9.5.5" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { @@ -2335,7 +2335,7 @@ "rss": "https://github.com/phly/phly-event-dispatcher/releases.atom", "source": "https://github.com/phly/phly-event-dispatcher" }, - "time": "2024-01-30T21:15:32+00:00" + "time": "2024-11-25T21:57:14+00:00" }, { "name": "psr/container", @@ -2776,21 +2776,21 @@ }, { "name": "spatie/yaml-front-matter", - "version": "2.0.9", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/spatie/yaml-front-matter.git", - "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392" + "reference": "5d0009289dd19a23e5f6cbb72c959a9fc1881e32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/cbe67e1cdd0a29a96d74ccab9400fe663e078392", - "reference": "cbe67e1cdd0a29a96d74ccab9400fe663e078392", + "url": "https://api.github.com/repos/spatie/yaml-front-matter/zipball/5d0009289dd19a23e5f6cbb72c959a9fc1881e32", + "reference": "5d0009289dd19a23e5f6cbb72c959a9fc1881e32", "shasum": "" }, "require": { - "php": "^7.0|^8.0", - "symfony/yaml": "^3.0|^4.0|^5.0|^6.0|^7.0" + "php": "^8.0", + "symfony/yaml": "^6.0|^7.0" }, "require-dev": { "phpunit/phpunit": "^9.0" @@ -2822,7 +2822,7 @@ "yaml" ], "support": { - "source": "https://github.com/spatie/yaml-front-matter/tree/2.0.9" + "source": "https://github.com/spatie/yaml-front-matter/tree/2.1.0" }, "funding": [ { @@ -2834,20 +2834,20 @@ "type": "github" } ], - "time": "2024-06-13T10:20:51+00:00" + "time": "2024-12-02T08:40:45+00:00" }, { "name": "symfony/console", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", - "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", "shasum": "" }, "require": { @@ -2911,7 +2911,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.8" + "source": "https://github.com/symfony/console/tree/v7.2.0" }, "funding": [ { @@ -2927,20 +2927,20 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:23:19+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -2978,7 +2978,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -2994,7 +2994,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher", @@ -3552,16 +3552,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -3615,7 +3615,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -3631,20 +3631,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/string", - "version": "v7.1.8", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", - "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { @@ -3702,7 +3702,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.8" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -3718,24 +3718,25 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:21+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/yaml", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671" + "reference": "099581e99f557e9f16b43c5916c26380b54abb22" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", - "reference": "3ced3f29e4f0d6bce2170ff26719f1fe9aacc671", + "url": "https://api.github.com/repos/symfony/yaml/zipball/099581e99f557e9f16b43c5916c26380b54abb22", + "reference": "099581e99f557e9f16b43c5916c26380b54abb22", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -3773,7 +3774,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.6" + "source": "https://github.com/symfony/yaml/tree/v7.2.0" }, "funding": [ { @@ -3789,7 +3790,7 @@ "type": "tidelift" } ], - "time": "2024-09-25T14:20:29+00:00" + "time": "2024-10-23T06:56:12+00:00" }, { "name": "webimpress/safe-writer", @@ -4772,16 +4773,16 @@ }, { "name": "laminas/laminas-code", - "version": "4.15.1", + "version": "4.16.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-code.git", - "reference": "877ad42fe9c164785182fca8afa3f416a056884d" + "reference": "1793e78dad4108b594084d05d1fb818b85b110af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-code/zipball/877ad42fe9c164785182fca8afa3f416a056884d", - "reference": "877ad42fe9c164785182fca8afa3f416a056884d", + "url": "https://api.github.com/repos/laminas/laminas-code/zipball/1793e78dad4108b594084d05d1fb818b85b110af", + "reference": "1793e78dad4108b594084d05d1fb818b85b110af", "shasum": "" }, "require": { @@ -4831,7 +4832,7 @@ "type": "community_bridge" } ], - "time": "2024-10-25T10:15:16+00:00" + "time": "2024-11-20T13:15:13+00:00" }, { "name": "laminas/laminas-coding-standard", @@ -4891,30 +4892,30 @@ }, { "name": "laminas/laminas-development-mode", - "version": "3.12.0", + "version": "3.13.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-development-mode.git", - "reference": "cd2f9885deab41ef590924d53ad4041db490b923" + "reference": "228efb56b5ecf16c0978082830a2887792b3a67c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-development-mode/zipball/cd2f9885deab41ef590924d53ad4041db490b923", - "reference": "cd2f9885deab41ef590924d53ad4041db490b923", + "url": "https://api.github.com/repos/laminas/laminas-development-mode/zipball/228efb56b5ecf16c0978082830a2887792b3a67c", + "reference": "228efb56b5ecf16c0978082830a2887792b3a67c", "shasum": "" }, "require": { - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" + "php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "conflict": { "zfcampus/zf-development-mode": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~2.5.0", - "mikey179/vfsstream": "^1.6.11", - "phpunit/phpunit": "^10.4.2", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.15.0" + "laminas/laminas-coding-standard": "~3.0.1", + "mikey179/vfsstream": "^1.6.12", + "phpunit/phpunit": "^10.5.38", + "psalm/plugin-phpunit": "^0.19.0", + "vimeo/psalm": "^5.26.1" }, "bin": [ "bin/laminas-development-mode" @@ -4948,7 +4949,7 @@ "type": "community_bridge" } ], - "time": "2023-11-21T16:03:48+00:00" + "time": "2024-11-21T21:25:13+00:00" }, { "name": "mezzio/mezzio-tooling", @@ -5954,12 +5955,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487" + "reference": "759d73e8fa031756f8e9b11858322cfd9ae9fbba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", - "reference": "9f1d9b2460cdd0422e8cfd58763bf3156ad7f487", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/759d73e8fa031756f8e9b11858322cfd9ae9fbba", + "reference": "759d73e8fa031756f8e9b11858322cfd9ae9fbba", "shasum": "" }, "conflict": { @@ -6005,7 +6006,7 @@ "azuracast/azuracast": "<0.18.3", "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2", "backpack/crud": "<3.4.9", - "backpack/filemanager": "<3.0.9", + "backpack/filemanager": "<2.0.2|>=3,<3.0.9", "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", "badaso/core": "<2.7", "bagisto/bagisto": "<2.1", @@ -6129,6 +6130,7 @@ "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26|>=3.3,<3.3.39", "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", + "ezsystems/ezplatform-http-cache": "<2.3.16", "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev|>=3.3,<3.3.40", @@ -6213,11 +6215,12 @@ "hov/jobfair": "<1.0.13|>=2,<2.0.2", "httpsoft/http-message": "<1.0.12", "hyn/multi-tenant": ">=5.6,<5.7.2", - "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6.0.0-beta1,<4.6.9", + "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6,<4.6.14", "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", "ibexa/fieldtype-richtext": ">=4.6,<4.6.10", "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", - "ibexa/post-install": "<=1.0.4", + "ibexa/http-cache": ">=4.6,<4.6.14", + "ibexa/post-install": "<1.0.16|>=4.6,<4.6.14", "ibexa/solr": ">=4.5,<4.5.4", "ibexa/user": ">=4,<4.4.3", "icecoder/icecoder": "<=8.1", @@ -6337,7 +6340,7 @@ "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.6|>=4.4,<4.4.4", + "moodle/moodle": "<4.3.8|>=4.4,<4.4.4", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", "movingbytes/social-network": "<=1.2.1", @@ -6425,7 +6428,7 @@ "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", "phpoffice/common": "<0.2.9", "phpoffice/phpexcel": "<1.8.1", - "phpoffice/phpspreadsheet": "<1.29.2|>=2,<2.1.1|>=2.2,<2.3", + "phpoffice/phpspreadsheet": "<1.29.4|>=2,<2.1.3|>=2.2,<2.3.2|>=3.3,<3.4", "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", "phpservermon/phpservermon": "<3.6", "phpsysinfo/phpsysinfo": "<3.4.3", @@ -6479,7 +6482,7 @@ "rap2hpoutre/laravel-log-viewer": "<0.13", "react/http": ">=0.7,<1.9", "really-simple-plugins/complianz-gdpr": "<6.4.2", - "redaxo/source": "<=5.17.1", + "redaxo/source": "<5.18", "remdex/livehelperchat": "<4.29", "reportico-web/reportico": "<=8.1", "rhukster/dom-sanitizer": "<1.0.7", @@ -6522,12 +6525,14 @@ "silverstripe/userforms": "<3|>=5,<5.4.2", "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", - "simplesamlphp/saml2": "<1.10.6|>=2,<2.3.8|>=3,<3.1.4|==5.0.0.0-alpha12", - "simplesamlphp/simplesamlphp": "<1.18.6", + "simplesamlphp/saml2": "<4.6.14|>=5.0.0.0-alpha1,<5.0.0.0-alpha18", + "simplesamlphp/saml2-legacy": "<4.6.14", + "simplesamlphp/simplesamlphp": "<2.0.15|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.4", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-openid": "<1", "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", - "simplesamlphp/xml-security": "==1.6.11", + "simplesamlphp/xml-common": "<1.20", + "simplesamlphp/xml-security": "<1.10", "simplito/elliptic-php": "<1.0.6", "sitegeist/fluid-components": "<3.5", "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", @@ -6535,18 +6540,19 @@ "slim/slim": "<2.6", "slub/slub-events": "<3.0.3", "smarty/smarty": "<4.5.3|>=5,<5.1.1", - "snipe/snipe-it": "<7.0.10", + "snipe/snipe-it": "<=7.0.13", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", "spatie/browsershot": "<3.57.4", "spatie/image-optimizer": "<1.7.3", + "spencer14420/sp-php-email-handler": "<1", "spipu/html2pdf": "<5.2.8", "spoon/library": "<1.4.1", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "ssddanbrown/bookstack": "<24.05.1", "starcitizentools/citizen-skin": ">=2.6.3,<2.31", - "statamic/cms": "<4.46|>=5.3,<5.6.2", + "statamic/cms": "<=5.16", "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.64", "studiomitte/friendlycaptcha": "<0.1.4", @@ -6593,13 +6599,14 @@ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/security-http": "<7.1.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/translation": ">=2,<2.0.17", "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/ux-autocomplete": "<2.11.2", "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", + "symfony/var-dumper": "<6.4.4|>=7,<7.0.4", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/webhook": ">=6.3,<6.3.8", @@ -6610,7 +6617,7 @@ "t3s/content-consent": "<1.0.3|>=2,<2.0.2", "tastyigniter/tastyigniter": "<3.3", "tcg/voyager": "<=1.4", - "tecnickcom/tcpdf": "<=6.7.4", + "tecnickcom/tcpdf": "<=6.7.5", "terminal42/contao-tablelookupwizard": "<3.3.5", "thelia/backoffice-default-template": ">=2.1,<2.1.2", "thelia/thelia": ">=2.1,<2.1.3", @@ -6787,7 +6794,7 @@ "type": "tidelift" } ], - "time": "2024-11-13T19:05:18+00:00" + "time": "2024-12-02T21:04:40+00:00" }, { "name": "sebastian/cli-parser", @@ -7848,16 +7855,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.1.6", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/c835867b3c62bb05c7fe3d637c871c7ae52024d4", - "reference": "c835867b3c62bb05c7fe3d637c871c7ae52024d4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { @@ -7894,7 +7901,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.6" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -7910,7 +7917,7 @@ "type": "tidelift" } ], - "time": "2024-10-25T15:11:02+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/process", @@ -8098,11 +8105,11 @@ "type": "project", "extra": { "branch-alias": { - "dev-master": "5.x-dev", - "dev-4.x": "4.x-dev", - "dev-3.x": "3.x-dev", + "dev-1.x": "1.x-dev", "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" + "dev-3.x": "3.x-dev", + "dev-4.x": "4.x-dev", + "dev-master": "5.x-dev" } }, "autoload": { From 832c04be9138d47c90c1077ba6f2d07b3a43dccd Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 02:32:09 +0000 Subject: [PATCH 30/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 54 ++++++++++++++++++++++--------------- composer.lock | 52 ++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 47 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index 4b8c5048..a4245bcc 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -695,6 +695,13 @@ "postcss": "^8.1.0" } }, + "node_modules/b4a": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", + "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/bach": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", @@ -881,9 +888,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001686", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001686.tgz", - "integrity": "sha512-Y7deg0Aergpa24M3qLC5xjNklnKnhsmSyR/V89dLZ1n0ucJIFNs7PgR2Yfa/Zf6W79SbBicgtGxZr2juHkEUIA==", + "version": "1.0.30001687", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", + "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", "dev": true, "funding": [ { @@ -1243,9 +1250,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.68", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.68.tgz", - "integrity": "sha512-FgMdJlma0OzUYlbrtZ4AeXjKxKPk6KT8WOP8BjcqxWtlg8qyJQjRzPJzUtUn5GBg1oQ26hFs7HOOHJMYiJRnvQ==", + "version": "1.5.71", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", + "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", "dev": true, "license": "ISC" }, @@ -2522,9 +2529,9 @@ } }, "node_modules/lilconfig": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", - "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", + "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", "dev": true, "license": "MIT", "engines": { @@ -3158,9 +3165,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.81.1", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.81.1.tgz", - "integrity": "sha512-VNLgf4FC5yFyKwAumAAwwNh8X4SevlVREq3Y8aDZIkm0lI/zO1feycMXQ4hn+eB6FVhRbleSQ1Yb/q8juSldTA==", + "version": "1.82.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.82.0.tgz", + "integrity": "sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==", "dev": true, "license": "MIT", "dependencies": { @@ -3301,9 +3308,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.20.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.2.tgz", - "integrity": "sha512-aDGDLU+j9tJcUdPGOaHmVF1u/hhI+CsGkT02V3OKlHDV7IukOI+nTWAGkiZEKCO35rWN1wIr4tS7YFr1f4qSvA==", + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", + "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", "dev": true, "license": "MIT", "dependencies": { @@ -3423,9 +3430,9 @@ } }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -3442,11 +3449,14 @@ } }, "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.2.tgz", + "integrity": "sha512-/MDslo7ZyWTA2vnk1j7XoDVfXsGk3tp+zFEJHJGm0UjIlQifonVFwlVbQDFh8KJzTBnT8ie115TYqir6bclddA==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } }, "node_modules/through2": { "version": "3.0.1", diff --git a/composer.lock b/composer.lock index 54198ed4..204c1e66 100644 --- a/composer.lock +++ b/composer.lock @@ -1059,16 +1059,16 @@ }, { "name": "league/commonmark", - "version": "2.5.3", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0" + "reference": "d150f911e0079e90ae3c106734c93137c184f932" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/b650144166dfa7703e62a22e493b853b58d874b0", - "reference": "b650144166dfa7703e62a22e493b853b58d874b0", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d150f911e0079e90ae3c106734c93137c184f932", + "reference": "d150f911e0079e90ae3c106734c93137c184f932", "shasum": "" }, "require": { @@ -1093,8 +1093,9 @@ "phpstan/phpstan": "^1.8.2", "phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0", "scrutinizer/ocular": "^1.8.1", - "symfony/finder": "^5.3 | ^6.0 || ^7.0", - "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0", + "symfony/finder": "^5.3 | ^6.0 | ^7.0", + "symfony/process": "^5.4 | ^6.0 | ^7.0", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 | ^7.0", "unleashedtech/php-coding-standard": "^3.1.1", "vimeo/psalm": "^4.24.0 || ^5.0.0" }, @@ -1104,7 +1105,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.6-dev" + "dev-main": "2.7-dev" } }, "autoload": { @@ -1161,7 +1162,7 @@ "type": "tidelift" } ], - "time": "2024-08-16T11:46:16+00:00" + "time": "2024-12-07T15:34:16+00:00" }, { "name": "league/config", @@ -1871,16 +1872,16 @@ }, { "name": "monolog/monolog", - "version": "3.8.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67" + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/32e515fdc02cdafbe4593e30a9350d486b125b67", - "reference": "32e515fdc02cdafbe4593e30a9350d486b125b67", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/aef6ee73a77a66e404dd6540934a9ef1b3c855b4", + "reference": "aef6ee73a77a66e404dd6540934a9ef1b3c855b4", "shasum": "" }, "require": { @@ -1958,7 +1959,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.8.0" + "source": "https://github.com/Seldaek/monolog/tree/3.8.1" }, "funding": [ { @@ -1970,7 +1971,7 @@ "type": "tidelift" } ], - "time": "2024-11-12T13:57:08+00:00" + "time": "2024-12-05T17:15:07+00:00" }, { "name": "nette/schema", @@ -5955,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "759d73e8fa031756f8e9b11858322cfd9ae9fbba" + "reference": "dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/759d73e8fa031756f8e9b11858322cfd9ae9fbba", - "reference": "759d73e8fa031756f8e9b11858322cfd9ae9fbba", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff", + "reference": "dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff", "shasum": "" }, "conflict": { @@ -6101,7 +6102,7 @@ "dolibarr/dolibarr": "<19.0.2", "dompdf/dompdf": "<2.0.4", "doublethreedigital/guest-entries": "<3.1.2", - "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.2.9|>=10.3,<10.3.6|>=11,<11.0.5", + "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.2.10|>=10.3,<10.3.6|>=11,<11.0.5", "drupal/core-recommended": ">=8,<10.2.9|>=10.3,<10.3.6|>=11,<11.0.5", "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<10.2.9|>=10.3,<10.3.6|>=11,<11.0.5", "duncanmcclean/guest-entries": "<3.1.2", @@ -6319,6 +6320,7 @@ "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", "maximebf/debugbar": "<1.19", "mdanter/ecc": "<2", + "mediawiki/abuse-filter": "<1.39.9|>=1.40,<1.41.3|>=1.42,<1.42.2", "mediawiki/cargo": "<3.6.1", "mediawiki/core": "<1.39.5|==1.40", "mediawiki/matomo": "<2.4.3", @@ -6494,6 +6496,7 @@ "s-cart/s-cart": "<6.9", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "samwilson/unlinked-wikibase": "<1.39.6|>=1.40,<1.40.2|>=1.41,<1.41.1", "scheb/two-factor-bundle": "<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", @@ -6525,14 +6528,14 @@ "silverstripe/userforms": "<3|>=5,<5.4.2", "silverstripe/versioned-admin": ">=1,<1.11.1", "simple-updates/phpwhois": "<=1", - "simplesamlphp/saml2": "<4.6.14|>=5.0.0.0-alpha1,<5.0.0.0-alpha18", + "simplesamlphp/saml2": "<4.6.14|==5.0.0.0-alpha12", "simplesamlphp/saml2-legacy": "<4.6.14", - "simplesamlphp/simplesamlphp": "<2.0.15|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.4", + "simplesamlphp/simplesamlphp": "<1.18.6", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-openid": "<1", "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", "simplesamlphp/xml-common": "<1.20", - "simplesamlphp/xml-security": "<1.10", + "simplesamlphp/xml-security": "==1.6.11", "simplito/elliptic-php": "<1.0.6", "sitegeist/fluid-components": "<3.5", "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", @@ -6599,14 +6602,13 @@ "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": "<7.1.8", + "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8", "symfony/translation": ">=2,<2.0.17", "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", "symfony/ux-autocomplete": "<2.11.2", "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", - "symfony/var-dumper": "<6.4.4|>=7,<7.0.4", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", "symfony/webhook": ">=6.3,<6.3.8", @@ -6623,7 +6625,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<3.2.2", + "thorsten/phpmyfaq": "<4", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -6794,7 +6796,7 @@ "type": "tidelift" } ], - "time": "2024-12-02T21:04:40+00:00" + "time": "2024-12-06T23:05:03+00:00" }, { "name": "sebastian/cli-parser", From 8d11b8699159d0189ebe7281a0eb9fd66453d45a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 00:29:14 +0000 Subject: [PATCH 31/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 68 +++++++++++++++---------------- composer.lock | 80 +++++++++++++++++++------------------ 2 files changed, 76 insertions(+), 72 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index a4245bcc..b072ad0e 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -50,9 +50,9 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "license": "MIT", "dependencies": { @@ -823,9 +823,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.2.tgz", - "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "version": "4.24.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", "dev": true, "funding": [ { @@ -843,9 +843,9 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001669", - "electron-to-chromium": "^1.5.41", - "node-releases": "^2.0.18", + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { @@ -888,9 +888,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001687", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001687.tgz", - "integrity": "sha512-0S/FDhf4ZiqrTUiQ39dKeUjYRjkv7lOZU1Dgif2rIqrTzX/1wV2hfKu9TOm1IHkdSijfLswxTFzl/cvir+SLSQ==", + "version": "1.0.30001688", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz", + "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==", "dev": true, "funding": [ { @@ -1250,9 +1250,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.71", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.71.tgz", - "integrity": "sha512-dB68l59BI75W1BUGVTAEJy45CEVuEGy9qPVVQ8pnHyHMn36PLPPoE1mjLH+lo9rKulO3HC2OhbACI/8tCqJBcA==", + "version": "1.5.73", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz", + "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==", "dev": true, "license": "ISC" }, @@ -2275,9 +2275,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -2634,9 +2634,9 @@ "optional": true }, "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "dev": true, "license": "MIT" }, @@ -3040,13 +3040,13 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.9", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", + "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -3165,9 +3165,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.82.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.82.0.tgz", - "integrity": "sha512-j4GMCTa8elGyN9A7x7bEglx0VgSpNUG4W4wNedQ33wSMdnkqQCT8HTwOaVSV4e6yQovcu/3Oc4coJP/l0xhL2Q==", + "version": "1.83.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.0.tgz", + "integrity": "sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==", "dev": true, "license": "MIT", "dependencies": { @@ -3308,9 +3308,9 @@ "license": "MIT" }, "node_modules/streamx": { - "version": "2.21.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.0.tgz", - "integrity": "sha512-Qz6MsDZXJ6ur9u+b+4xCG18TluU7PGlRfXVAAjNiGsFrBUt/ioyLkxbFaKJygoPs+/kW4VyBj0bSj89Qu0IGyg==", + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.21.1.tgz", + "integrity": "sha512-PhP9wUnFLa+91CPy3N6tiQsK+gnYyUNuk15S3YG/zjYE7RuPeCjJngqnzpC31ow0lzBHQ+QGO4cNJnd0djYUsw==", "dev": true, "license": "MIT", "dependencies": { @@ -3449,9 +3449,9 @@ } }, "node_modules/text-decoder": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.2.tgz", - "integrity": "sha512-/MDslo7ZyWTA2vnk1j7XoDVfXsGk3tp+zFEJHJGm0UjIlQifonVFwlVbQDFh8KJzTBnT8ie115TYqir6bclddA==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", "dev": true, "license": "Apache-2.0", "dependencies": { diff --git a/composer.lock b/composer.lock index 204c1e66..1bff650a 100644 --- a/composer.lock +++ b/composer.lock @@ -2839,16 +2839,16 @@ }, { "name": "symfony/console", - "version": "v7.2.0", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", - "reference": "23c8aae6d764e2bae02d2a99f7532a7f6ed619cf", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { @@ -2912,7 +2912,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.0" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -2928,7 +2928,7 @@ "type": "tidelift" } ], - "time": "2024-11-06T14:24:19+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/deprecation-contracts", @@ -3179,8 +3179,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3255,8 +3255,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3333,8 +3333,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3417,8 +3417,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3491,8 +3491,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -5791,16 +5791,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.38", + "version": "10.5.39", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132" + "reference": "4e89eff200b801db58f3d580ad7426431949eaa9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a86773b9e887a67bc53efa9da9ad6e3f2498c132", - "reference": "a86773b9e887a67bc53efa9da9ad6e3f2498c132", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4e89eff200b801db58f3d580ad7426431949eaa9", + "reference": "4e89eff200b801db58f3d580ad7426431949eaa9", "shasum": "" }, "require": { @@ -5810,7 +5810,7 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.1", @@ -5872,7 +5872,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.38" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.39" }, "funding": [ { @@ -5888,7 +5888,7 @@ "type": "tidelift" } ], - "time": "2024-10-28T13:06:21+00:00" + "time": "2024-12-11T10:51:07+00:00" }, { "name": "psalm/plugin-phpunit", @@ -5956,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff" + "reference": "233f7c395ac3b83e3c85aa304f3350bf8897aca5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff", - "reference": "dcb2bdb48e1d9b0b5b1c333b61f49772aee879ff", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/233f7c395ac3b83e3c85aa304f3350bf8897aca5", + "reference": "233f7c395ac3b83e3c85aa304f3350bf8897aca5", "shasum": "" }, "conflict": { @@ -6102,9 +6102,9 @@ "dolibarr/dolibarr": "<19.0.2", "dompdf/dompdf": "<2.0.4", "doublethreedigital/guest-entries": "<3.1.2", - "drupal/core": ">=6,<6.38|>=7,<7.96|>=8,<10.2.10|>=10.3,<10.3.6|>=11,<11.0.5", - "drupal/core-recommended": ">=8,<10.2.9|>=10.3,<10.3.6|>=11,<11.0.5", - "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.80|>=8,<10.2.9|>=10.3,<10.3.6|>=11,<11.0.5", + "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", "duncanmcclean/guest-entries": "<3.1.2", "dweeves/magmi": "<=0.7.24", "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", @@ -6285,12 +6285,13 @@ "laravel/fortify": "<1.11.1", "laravel/framework": "<6.20.45|>=7,<7.30.7|>=8,<8.83.28|>=9,<9.52.17|>=10,<10.48.23|>=11,<11.31", "laravel/laravel": ">=5.4,<5.4.22", + "laravel/pulse": "<1.3.1", "laravel/reverb": "<1.4", "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", "lavalite/cms": "<=9|==10.1", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", - "league/commonmark": "<0.18.3", + "league/commonmark": "<2.6", "league/flysystem": "<1.1.4|>=2,<2.1.1", "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", @@ -6365,6 +6366,7 @@ "neos/swiftmailer": "<5.4.5", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", + "nette/database": "<=3.2.4", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", "nilsteampassnet/teampass": "<3.0.10", "nonfiction/nterchange": "<4.1.1", @@ -6501,7 +6503,7 @@ "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", "sfroemken/url_redirect": "<=1.2.1", - "sheng/yiicms": "<=1.2", + "sheng/yiicms": "<1.2.1", "shopware/core": "<=6.5.8.12|>=6.6,<=6.6.5", "shopware/platform": "<=6.5.8.12|>=6.6,<=6.6.5", "shopware/production": "<=6.3.5.2", @@ -6509,6 +6511,7 @@ "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopxo/shopxo": "<=6.1", "showdoc/showdoc": "<2.10.4", + "shuchkin/simplexlsx": ">=1.0.12,<1.1.12", "silverstripe-australia/advancedreports": ">=1,<=2", "silverstripe/admin": "<1.13.19|>=2,<2.1.8", "silverstripe/assets": ">=1,<1.11.1", @@ -6546,7 +6549,7 @@ "snipe/snipe-it": "<=7.0.13", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", - "spatie/browsershot": "<3.57.4", + "spatie/browsershot": "<5.0.1", "spatie/image-optimizer": "<1.7.3", "spencer14420/sp-php-email-handler": "<1", "spipu/html2pdf": "<5.2.8", @@ -6691,6 +6694,7 @@ "wikimedia/parsoid": "<0.12.2", "willdurand/js-translation-bundle": "<2.1.1", "winter/wn-backend-module": "<1.2.4", + "winter/wn-cms-module": "<1.0.476|>=1.1,<1.1.11|>=1.2,<1.2.7", "winter/wn-dusk-plugin": "<2.1", "winter/wn-system-module": "<1.2.4", "wintercms/winter": "<=1.2.3", @@ -6796,7 +6800,7 @@ "type": "tidelift" } ], - "time": "2024-12-06T23:05:03+00:00" + "time": "2024-12-13T21:04:51+00:00" }, { "name": "sebastian/cli-parser", @@ -7777,16 +7781,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.11.1", + "version": "3.11.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87" + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", - "reference": "19473c30efe4f7b3cd42522d0b2e6e7f243c6f87", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/1368f4a58c3c52114b86b1abe8f4098869cb0079", + "reference": "1368f4a58c3c52114b86b1abe8f4098869cb0079", "shasum": "" }, "require": { @@ -7853,7 +7857,7 @@ "type": "open_collective" } ], - "time": "2024-11-16T12:02:36+00:00" + "time": "2024-12-11T16:04:26+00:00" }, { "name": "symfony/filesystem", From 7e7cf9525cdf6dcac0d62c278d7bdfc21339e1a1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 01:42:56 +0000 Subject: [PATCH 32/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 39 +++++++++++---------- composer.lock | 68 ++++++++++++++++++------------------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index b072ad0e..c4dd26c6 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -888,9 +888,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001688", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001688.tgz", - "integrity": "sha512-Nmqpru91cuABu/DTCXbM2NSRHzM2uVHfPnhJ/1zEAJx/ILBRVmz3pzH4N7DZqbdG0gWClsCC05Oj0mJ/1AWMbA==", + "version": "1.0.30001690", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", "dev": true, "funding": [ { @@ -1250,9 +1250,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.73", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.73.tgz", - "integrity": "sha512-8wGNxG9tAG5KhGd3eeA0o6ixhiNdgr0DcHWm85XPCphwZgD1lIEoi6t3VERayWao7SF7AAZTw6oARGJeVjH8Kg==", + "version": "1.5.75", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", + "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", "dev": true, "license": "ISC" }, @@ -1999,9 +1999,9 @@ } }, "node_modules/gulp-rev-all/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz", + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==", "dev": true, "license": "MIT", "engines": { @@ -2275,9 +2275,9 @@ } }, "node_modules/is-core-module": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", - "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", "dependencies": { @@ -3040,9 +3040,9 @@ } }, "node_modules/resolve": { - "version": "1.22.9", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", - "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", "dev": true, "license": "MIT", "dependencies": { @@ -3053,6 +3053,9 @@ "bin": { "resolve": "bin/resolve" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3186,9 +3189,9 @@ } }, "node_modules/sass/node_modules/chokidar": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", - "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, "license": "MIT", "dependencies": { diff --git a/composer.lock b/composer.lock index 1bff650a..6687ba70 100644 --- a/composer.lock +++ b/composer.lock @@ -494,8 +494,8 @@ "type": "library", "extra": { "laminas": { - "config-provider": "Laminas\\Diactoros\\ConfigProvider", - "module": "Laminas\\Diactoros" + "module": "Laminas\\Diactoros", + "config-provider": "Laminas\\Diactoros\\ConfigProvider" } }, "autoload": { @@ -543,16 +543,16 @@ }, { "name": "laminas/laminas-escaper", - "version": "2.14.0", + "version": "2.15.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb" + "reference": "c612b0488ae486284c39885efca494c180f16351" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/0f7cb975f4443cf22f33408925c231225cfba8cb", - "reference": "0f7cb975f4443cf22f33408925c231225cfba8cb", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/c612b0488ae486284c39885efca494c180f16351", + "reference": "c612b0488ae486284c39885efca494c180f16351", "shasum": "" }, "require": { @@ -564,12 +564,12 @@ "zendframework/zend-escaper": "*" }, "require-dev": { - "infection/infection": "^0.27.9", - "laminas/laminas-coding-standard": "~3.0.0", + "infection/infection": "^0.27.11", + "laminas/laminas-coding-standard": "~3.0.1", "maglnet/composer-require-checker": "^3.8.0", - "phpunit/phpunit": "^9.6.16", + "phpunit/phpunit": "^9.6.22", "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "^5.21.1" + "vimeo/psalm": "^5.26.1" }, "type": "library", "autoload": { @@ -601,7 +601,7 @@ "type": "community_bridge" } ], - "time": "2024-10-24T10:12:53+00:00" + "time": "2024-12-17T19:39:54+00:00" }, { "name": "laminas/laminas-feed", @@ -2709,16 +2709,16 @@ }, { "name": "spatie/array-to-xml", - "version": "3.3.0", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/spatie/array-to-xml.git", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876" + "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/f56b220fe2db1ade4c88098d83413ebdfc3bf876", - "reference": "f56b220fe2db1ade4c88098d83413ebdfc3bf876", + "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", + "reference": "7dcfc67d60b0272926dabad1ec01f6b8a5fb5e67", "shasum": "" }, "require": { @@ -2761,7 +2761,7 @@ "xml" ], "support": { - "source": "https://github.com/spatie/array-to-xml/tree/3.3.0" + "source": "https://github.com/spatie/array-to-xml/tree/3.4.0" }, "funding": [ { @@ -2773,7 +2773,7 @@ "type": "github" } ], - "time": "2024-05-01T10:20:27+00:00" + "time": "2024-12-16T12:45:15+00:00" }, { "name": "spatie/yaml-front-matter", @@ -4228,13 +4228,13 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - }, "phpstan": { "includes": [ "extension.neon" ] + }, + "branch-alias": { + "dev-main": "3.x-dev" } }, "autoload": { @@ -5791,16 +5791,16 @@ }, { "name": "phpunit/phpunit", - "version": "10.5.39", + "version": "10.5.40", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "4e89eff200b801db58f3d580ad7426431949eaa9" + "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4e89eff200b801db58f3d580ad7426431949eaa9", - "reference": "4e89eff200b801db58f3d580ad7426431949eaa9", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e6ddda95af52f69c1e0c7b4f977cccb58048798c", + "reference": "e6ddda95af52f69c1e0c7b4f977cccb58048798c", "shasum": "" }, "require": { @@ -5872,7 +5872,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.39" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.40" }, "funding": [ { @@ -5888,7 +5888,7 @@ "type": "tidelift" } ], - "time": "2024-12-11T10:51:07+00:00" + "time": "2024-12-21T05:49:06+00:00" }, { "name": "psalm/plugin-phpunit", @@ -5956,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "233f7c395ac3b83e3c85aa304f3350bf8897aca5" + "reference": "abbccc97f36a9c78f033525c019d310433f22b57" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/233f7c395ac3b83e3c85aa304f3350bf8897aca5", - "reference": "233f7c395ac3b83e3c85aa304f3350bf8897aca5", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/abbccc97f36a9c78f033525c019d310433f22b57", + "reference": "abbccc97f36a9c78f033525c019d310433f22b57", "shasum": "" }, "conflict": { @@ -6071,7 +6071,7 @@ "contao/managed-edition": "<=1.5", "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", - "craftcms/cms": "<=4.12.6.1|>=5,<=5.4.7.1", + "craftcms/cms": "<4.13.2|>=5,<5.5.2", "croogo/croogo": "<4", "cuyz/valinor": "<0.12", "czim/file-handling": "<1.5|>=2,<2.3", @@ -6250,6 +6250,7 @@ "james-heinrich/phpthumb": "<1.7.12", "jasig/phpcas": "<1.3.3", "jcbrand/converse.js": "<3.3.3", + "joelbutcher/socialstream": "<6.2", "johnbillion/wp-crontrol": "<1.16.2", "joomla/application": "<1.0.13", "joomla/archive": "<1.1.12|>=2,<2.0.1", @@ -6366,7 +6367,6 @@ "neos/swiftmailer": "<5.4.5", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", - "nette/database": "<=3.2.4", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", "nilsteampassnet/teampass": "<3.0.10", "nonfiction/nterchange": "<4.1.1", @@ -6549,7 +6549,7 @@ "snipe/snipe-it": "<=7.0.13", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", - "spatie/browsershot": "<5.0.1", + "spatie/browsershot": "<5.0.3", "spatie/image-optimizer": "<1.7.3", "spencer14420/sp-php-email-handler": "<1", "spipu/html2pdf": "<5.2.8", @@ -6662,7 +6662,7 @@ "typo3fluid/fluid": ">=2,<2.0.8|>=2.1,<2.1.7|>=2.2,<2.2.4|>=2.3,<2.3.7|>=2.4,<2.4.4|>=2.5,<2.5.11|>=2.6,<2.6.10", "ua-parser/uap-php": "<3.8", "uasoft-indonesia/badaso": "<=2.9.7", - "unisharp/laravel-filemanager": "<2.6.4", + "unisharp/laravel-filemanager": "<2.9.1", "unopim/unopim": "<0.1.5", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", @@ -6800,7 +6800,7 @@ "type": "tidelift" } ], - "time": "2024-12-13T21:04:51+00:00" + "time": "2024-12-20T16:05:39+00:00" }, { "name": "sebastian/cli-parser", From 47412363f0fb3aa2cc112ee97f00b19abe2daf21 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 00:32:31 +0000 Subject: [PATCH 33/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 12 ++++----- composer.lock | 50 +++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index c4dd26c6..d444226c 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -1250,9 +1250,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.75", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.75.tgz", - "integrity": "sha512-Lf3++DumRE/QmweGjU+ZcKqQ+3bKkU/qjaKYhIJKEOhgIO9Xs6IiAQFkfFoj+RhgDk4LUeNsLo6plExHqSyu6Q==", + "version": "1.5.76", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", + "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", "dev": true, "license": "ISC" }, @@ -1385,9 +1385,9 @@ } }, "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.18.0.tgz", + "integrity": "sha512-QKHXPW0hD8g4UET03SdOdunzSouc9N4AuHdsX8XNcTsuz+yYFILVNIX4l9yHABMhiEI9Db0JTTIpu0wB+Y1QQw==", "dev": true, "license": "ISC", "dependencies": { diff --git a/composer.lock b/composer.lock index 6687ba70..278d8e4d 100644 --- a/composer.lock +++ b/composer.lock @@ -1059,16 +1059,16 @@ }, { "name": "league/commonmark", - "version": "2.6.0", + "version": "2.6.1", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "d150f911e0079e90ae3c106734c93137c184f932" + "reference": "d990688c91cedfb69753ffc2512727ec646df2ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d150f911e0079e90ae3c106734c93137c184f932", - "reference": "d150f911e0079e90ae3c106734c93137c184f932", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/d990688c91cedfb69753ffc2512727ec646df2ad", + "reference": "d990688c91cedfb69753ffc2512727ec646df2ad", "shasum": "" }, "require": { @@ -1162,7 +1162,7 @@ "type": "tidelift" } ], - "time": "2024-12-07T15:34:16+00:00" + "time": "2024-12-29T14:10:59+00:00" }, { "name": "league/config", @@ -2949,12 +2949,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3097,12 +3097,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3575,12 +3575,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -5956,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "abbccc97f36a9c78f033525c019d310433f22b57" + "reference": "9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/abbccc97f36a9c78f033525c019d310433f22b57", - "reference": "abbccc97f36a9c78f033525c019d310433f22b57", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d", + "reference": "9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d", "shasum": "" }, "conflict": { @@ -6250,7 +6250,7 @@ "james-heinrich/phpthumb": "<1.7.12", "jasig/phpcas": "<1.3.3", "jcbrand/converse.js": "<3.3.3", - "joelbutcher/socialstream": "<6.2", + "joelbutcher/socialstream": "<5.6|>=6,<6.2", "johnbillion/wp-crontrol": "<1.16.2", "joomla/application": "<1.0.13", "joomla/archive": "<1.1.12|>=2,<2.0.1", @@ -6511,7 +6511,7 @@ "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", "shopxo/shopxo": "<=6.1", "showdoc/showdoc": "<2.10.4", - "shuchkin/simplexlsx": ">=1.0.12,<1.1.12", + "shuchkin/simplexlsx": ">=1.0.12,<1.1.13", "silverstripe-australia/advancedreports": ">=1,<=2", "silverstripe/admin": "<1.13.19|>=2,<2.1.8", "silverstripe/assets": ">=1,<1.11.1", @@ -6622,7 +6622,8 @@ "t3s/content-consent": "<1.0.3|>=2,<2.0.2", "tastyigniter/tastyigniter": "<3.3", "tcg/voyager": "<=1.4", - "tecnickcom/tcpdf": "<=6.7.5", + "tecnickcom/tc-lib-pdf-font": "<2.6.4", + "tecnickcom/tcpdf": "<6.8", "terminal42/contao-tablelookupwizard": "<3.3.5", "thelia/backoffice-default-template": ">=2.1,<2.1.2", "thelia/thelia": ">=2.1,<2.1.3", @@ -6634,6 +6635,7 @@ "tinymce/tinymce": "<7.2", "tinymighty/wiki-seo": "<1.2.2", "titon/framework": "<9.9.99", + "tltneon/lgsl": "<7", "tobiasbg/tablepress": "<=2.0.0.0-RC1", "topthink/framework": "<6.0.17|>=6.1,<=8.0.4", "topthink/think": "<=6.1.1", @@ -6800,7 +6802,7 @@ "type": "tidelift" } ], - "time": "2024-12-20T16:05:39+00:00" + "time": "2024-12-27T20:05:23+00:00" }, { "name": "sebastian/cli-parser", From 8b1a5932f398180f58d1f0eb24f445d3e031d498 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 01:19:57 +0000 Subject: [PATCH 34/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 26 +++++++++++++------------- composer.lock | 18 +++++++++--------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index d444226c..3f90671a 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -725,9 +725,9 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.1.tgz", + "integrity": "sha512-Bw2PgKSrZ3uCuSV9WQ998c/GTJTd+9bWj97n7aDQMP8dP/exAZQlJeswPty0ISy+HZD+9Ex+C7CCnc9Q5QJFmQ==", "dev": true, "license": "Apache-2.0", "optional": true @@ -1348,9 +1348,9 @@ "license": "MIT" }, "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", "dev": true, "license": "MIT", "dependencies": { @@ -1358,7 +1358,7 @@ "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.8" }, "engines": { "node": ">=8.6.0" @@ -3168,9 +3168,9 @@ "license": "MIT" }, "node_modules/sass": { - "version": "1.83.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.0.tgz", - "integrity": "sha512-qsSxlayzoOjdvXMVLkzF84DJFc2HZEL/rFyGIKbbilYtAvlCxyuzUeff9LawTn4btVnLKg75Z8MMr1lxU1lfGw==", + "version": "1.83.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.83.1.tgz", + "integrity": "sha512-EVJbDaEs4Rr3F0glJzFSOvtg2/oy2V/YrGFPqPY24UqcLDWcI9ZY5sN+qyO3c/QCZwzgfirvhXvINiJCE/OLcA==", "dev": true, "license": "MIT", "dependencies": { @@ -3850,9 +3850,9 @@ } }, "node_modules/yaml": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", - "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", "dev": true, "license": "ISC", "bin": { diff --git a/composer.lock b/composer.lock index 278d8e4d..f4281f83 100644 --- a/composer.lock +++ b/composer.lock @@ -5956,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d" + "reference": "0739463889fe714daa685817789aef000c6774cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d", - "reference": "9dd07280fc4c5f6c3d2a3da5e4058fc7288c2a1d", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0739463889fe714daa685817789aef000c6774cc", + "reference": "0739463889fe714daa685817789aef000c6774cc", "shasum": "" }, "conflict": { @@ -6083,7 +6083,7 @@ "datatables/datatables": "<1.10.10", "david-garcia/phpwhois": "<=4.3.1", "dbrisinajumi/d2files": "<1", - "dcat/laravel-admin": "<=2.1.3", + "dcat/laravel-admin": "<=2.1.3|==2.2.0.0-beta|==2.2.2.0-beta", "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", "desperado/xml-bundle": "<=0.1.7", @@ -6368,7 +6368,7 @@ "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", - "nilsteampassnet/teampass": "<3.0.10", + "nilsteampassnet/teampass": "<3.1.3.1-dev", "nonfiction/nterchange": "<4.1.1", "notrinos/notrinos-erp": "<=0.7", "noumo/easyii": "<=0.9", @@ -6429,10 +6429,10 @@ "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.1", - "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5", + "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5|>=3.2.10,<=4.0.1", "phpoffice/common": "<0.2.9", "phpoffice/phpexcel": "<1.8.1", - "phpoffice/phpspreadsheet": "<1.29.4|>=2,<2.1.3|>=2.2,<2.3.2|>=3.3,<3.4", + "phpoffice/phpspreadsheet": "<=1.29.6|>=2,<=2.1.5|>=2.2,<=2.3.4|>=3,<3.7", "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", "phpservermon/phpservermon": "<3.6", "phpsysinfo/phpsysinfo": "<3.4.3", @@ -6629,7 +6629,7 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<4", + "thorsten/phpmyfaq": "<=4.0.1", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", "tinymce/tinymce": "<7.2", @@ -6802,7 +6802,7 @@ "type": "tidelift" } ], - "time": "2024-12-27T20:05:23+00:00" + "time": "2025-01-03T17:04:48+00:00" }, { "name": "sebastian/cli-parser", From ab3595348d13ff1add90e915cdf08e5d22d0c30f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 Jan 2025 01:52:45 +0000 Subject: [PATCH 35/38] Lock file maintenance Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- bootstrap/package-lock.json | 40 ++++++++++++++++++------------------- composer.lock | 14 ++++++++----- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/bootstrap/package-lock.json b/bootstrap/package-lock.json index 3f90671a..56787526 100644 --- a/bootstrap/package-lock.json +++ b/bootstrap/package-lock.json @@ -725,9 +725,9 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.1.tgz", - "integrity": "sha512-Bw2PgKSrZ3uCuSV9WQ998c/GTJTd+9bWj97n7aDQMP8dP/exAZQlJeswPty0ISy+HZD+9Ex+C7CCnc9Q5QJFmQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", + "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", "dev": true, "license": "Apache-2.0", "optional": true @@ -823,9 +823,9 @@ } }, "node_modules/browserslist": { - "version": "4.24.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.3.tgz", - "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "version": "4.24.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz", + "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==", "dev": true, "funding": [ { @@ -888,9 +888,9 @@ "license": "MIT" }, "node_modules/caniuse-lite": { - "version": "1.0.30001690", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", - "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "version": "1.0.30001692", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001692.tgz", + "integrity": "sha512-A95VKan0kdtrsnMubMKxEKUKImOPSuCpYgxSQBo036P5YYgVIcOYJEgt/txJWqObiRQeISNCfef9nvlQ0vbV7A==", "dev": true, "funding": [ { @@ -1250,9 +1250,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.76", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", - "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", + "version": "1.5.80", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.80.tgz", + "integrity": "sha512-LTrKpW0AqIuHwmlVNV+cjFYTnXtM9K37OGhpe0ZI10ScPSxqVSryZHIY3WnCS5NSYbBODRTZyhRMS2h5FAEqAw==", "dev": true, "license": "ISC" }, @@ -3205,13 +3205,13 @@ } }, "node_modules/sass/node_modules/readdirp": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", - "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.1.tgz", + "integrity": "sha512-h80JrZu/MHUZCyHu5ciuoI0+WxsCxzxJTILn6Fs8rxSnFPh+UVHYfeIxK1nVGugMqkfC4vJcBOYbkfkwYK0+gw==", "dev": true, "license": "MIT", "engines": { - "node": ">= 14.16.0" + "node": ">= 14.18.0" }, "funding": { "type": "individual", @@ -3534,9 +3534,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", + "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", "dev": true, "funding": [ { @@ -3555,7 +3555,7 @@ "license": "MIT", "dependencies": { "escalade": "^3.2.0", - "picocolors": "^1.1.0" + "picocolors": "^1.1.1" }, "bin": { "update-browserslist-db": "cli.js" diff --git a/composer.lock b/composer.lock index f4281f83..800aa010 100644 --- a/composer.lock +++ b/composer.lock @@ -5956,12 +5956,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "0739463889fe714daa685817789aef000c6774cc" + "reference": "a717959d5f0bf7c9a881efdbb7ec0da4454a14ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/0739463889fe714daa685817789aef000c6774cc", - "reference": "0739463889fe714daa685817789aef000c6774cc", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/a717959d5f0bf7c9a881efdbb7ec0da4454a14ac", + "reference": "a717959d5f0bf7c9a881efdbb7ec0da4454a14ac", "shasum": "" }, "conflict": { @@ -6205,6 +6205,7 @@ "grumpydictator/firefly-iii": "<6.1.17", "gugoan/economizzer": "<=0.9.0.0-beta1", "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", + "guzzlehttp/oauth-subscriber": "<0.8.1", "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", "harvesthq/chosen": "<1.8.7", @@ -6365,6 +6366,8 @@ "neos/media-browser": "<7.3.19|>=8,<8.0.16|>=8.1,<8.1.11|>=8.2,<8.2.11|>=8.3,<8.3.9", "neos/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<5.3.10|>=7,<7.0.9|>=7.1,<7.1.7|>=7.2,<7.2.6|>=7.3,<7.3.4|>=8,<8.0.2", "neos/swiftmailer": "<5.4.5", + "nesbot/carbon": "<2.72.6|>=3,<3.8.4", + "netcarver/textile": "<=4.1.2", "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", @@ -6558,6 +6561,7 @@ "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "ssddanbrown/bookstack": "<24.05.1", "starcitizentools/citizen-skin": ">=2.6.3,<2.31", + "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2", "statamic/cms": "<=5.16", "stormpath/sdk": "<9.9.99", "studio-42/elfinder": "<=2.1.64", @@ -6713,7 +6717,7 @@ "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", "yeswiki/yeswiki": "<=4.4.4", - "yetiforce/yetiforce-crm": "<=6.4", + "yetiforce/yetiforce-crm": "<6.5", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", "yiisoft/yii": "<1.1.29", @@ -6802,7 +6806,7 @@ "type": "tidelift" } ], - "time": "2025-01-03T17:04:48+00:00" + "time": "2025-01-08T21:04:52+00:00" }, { "name": "sebastian/cli-parser", From fcc8c6c0bac8c5863fdacf173d11cf88fe2cd99b Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 19 Nov 2024 10:55:24 +0200 Subject: [PATCH 36/38] listing page redesign, data refresh cron changes, db no longer regenerated per build Signed-off-by: Jurj-Bogdan --- src/Ecosystem/Console/CreateEcosystemDatabase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 06da725a..7b0b4ff3 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -420,7 +420,6 @@ private function getPackageData(array $userData): ?array return [ 'id' => uniqid($packageData['name']), 'name' => $packageData['name'], - 'type' => $packageData['type'], 'repository' => $packageData['repository'], 'description' => $packageData['description'], 'created' => $timestamp, From 3fc424b8bd29481685912cbb6ca9ccc26c7a7086 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 14 Jan 2025 13:52:10 +0200 Subject: [PATCH 37/38] package removal logic, psalm fixes, initial unit tests Signed-off-by: Jurj-Bogdan --- ADD_ECOSYSTEM_PACKAGE.md | 18 +- composer.json | 2 + composer.lock | 7 +- psalm-baseline.xml | 95 +++++++++- .../Console/CreateEcosystemDatabase.php | 174 +++++------------- .../Console/SeedEcosystemDatabase.php | 133 ++++++------- .../CreateEcosystemPackageFromArrayTrait.php | 20 +- src/Ecosystem/EcosystemConnectionTrait.php | 83 +++++++++ src/Ecosystem/EcosystemPackage.php | 3 + src/Ecosystem/Handler/EcosystemHandler.php | 14 +- src/Ecosystem/Mapper/MapperInterface.php | 4 +- src/Ecosystem/Mapper/PdoMapper.php | 20 +- src/Ecosystem/Mapper/PdoPaginator.php | 2 +- test/Unit/Ecosystem/CommonTestCase.php | 20 ++ test/Unit/Ecosystem/ConfigProviderTest.php | 85 +++++++++ .../CreateEcosystemDatabaseDelegatorTest.php | 49 +++++ .../Console/CreateEcosystemDatabaseTest.php | 31 ++++ .../SeedEcosystemDatabaseDelegatorTest.php | 45 +++++ ...eateEcosystemPackageFromArrayTraitTest.php | 93 ++++++++++ .../Handler/EcosystemHandlerFactoryTest.php | 36 ++++ .../Ecosystem/Mapper/MapperFactoryTest.php | 31 ++++ 21 files changed, 725 insertions(+), 240 deletions(-) create mode 100644 src/Ecosystem/EcosystemConnectionTrait.php create mode 100644 test/Unit/Ecosystem/CommonTestCase.php create mode 100644 test/Unit/Ecosystem/ConfigProviderTest.php create mode 100644 test/Unit/Ecosystem/Console/CreateEcosystemDatabaseDelegatorTest.php create mode 100644 test/Unit/Ecosystem/Console/CreateEcosystemDatabaseTest.php create mode 100644 test/Unit/Ecosystem/Console/SeedEcosystemDatabaseDelegatorTest.php create mode 100644 test/Unit/Ecosystem/CreateEcosystemPackageFromArrayTraitTest.php create mode 100644 test/Unit/Ecosystem/Handler/EcosystemHandlerFactoryTest.php create mode 100644 test/Unit/Ecosystem/Mapper/MapperFactoryTest.php diff --git a/ADD_ECOSYSTEM_PACKAGE.md b/ADD_ECOSYSTEM_PACKAGE.md index b4324658..12009ada 100644 --- a/ADD_ECOSYSTEM_PACKAGE.md +++ b/ADD_ECOSYSTEM_PACKAGE.md @@ -14,13 +14,15 @@ composer build > The following command can be run individually for testing: ```bash -./vendor/bin/laminas ecosystem:create-db +./vendor/bin/laminas ecosystem:create-db --github-token= [--force-rebuild] ``` +> the optional "--force-rebuild" flag will regenerate the database completely, not only add and/or remove packages + *Used for creating the database.* ```bash -./vendor/bin/laminas ecosystem:seed-db +./vendor/bin/laminas ecosystem:seed-db --github-token= ``` *Used for updating the package data every X hours.* @@ -30,21 +32,18 @@ composer build ```json { "packagistUrl": "", - "githubUrl": "", "keywords": [], "homepage": "", - "category": "" + "category": "", + "usage": "" } ``` ### New entry fields description -- `packagistUrl` **required** +- `packagistUrl` **string** - the packagist URL of the entry, with no query parameters -- `githubUrl` - **string** - optional link to be displayed on the package card - - `keywords` **array of strings** - user defined keywords used for filtering results @@ -53,3 +52,6 @@ composer build - `category` **string** - package category must be one of "skeleton", "integration", "tool" + +- `usage` + **string** - package usage must be one of "mezzio" or "mvc" diff --git a/composer.json b/composer.json index f37e1f1b..3f3a3715 100644 --- a/composer.json +++ b/composer.json @@ -37,6 +37,7 @@ "php": "~8.3.0", "ext-curl": "*", "ext-pdo": "*", + "ext-sqlite3": "*", "dflydev/fig-cookies": "^3.1.0", "laminas/laminas-cli": "^1.11.0", "laminas/laminas-component-installer": "^3.5.0", @@ -83,6 +84,7 @@ }, "autoload-dev": { "psr-4": { + "LaminasTest\\Unit\\": "test/Unit" } }, "scripts": { diff --git a/composer.lock b/composer.lock index 800aa010..2cbea4d5 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": "1ed74b4fb82d276ddf9c7aa5b58a3dbb", + "content-hash": "a36965512c279d30245a06c210966571", "packages": [ { "name": "brick/varexporter", @@ -8217,9 +8217,10 @@ "prefer-lowest": false, "platform": { "php": "~8.3.0", + "ext-curl": "*", "ext-pdo": "*", - "ext-curl": "*" + "ext-sqlite3": "*" }, - "platform-dev": {}, + "platform-dev": [], "plugin-api-version": "2.6.0" } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 247dad1f..180562ab 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + @@ -225,6 +225,62 @@ template->url('blog.post', ['id' => $post->id])]]> + + + + + + ghToken]]> + + + + + + + + + + + + + ghToken]]> + + + + + + + + + + ghToken]]> + + + + + + + + + + + + + + + + + + + + + + + + + CreateEcosystemPackageFromArray(...)]]> + + @@ -299,4 +355,41 @@ + + + config['dependencies']]]> + config['dependencies']]]> + config['dependencies']]]> + config['ecosystem']]]> + config['laminas-cli']]]> + config['laminas-cli']['commands']]]> + config['laminas-cli']['commands']]]> + config['templates']]]> + config['templates']['paths']['ecosystem'][0]]]> + + + config['dependencies']['delegators']]]> + config['dependencies']['factories']]]> + config['dependencies']['invokables']]]> + config['laminas-cli']['commands']]]> + config['laminas-cli']['commands']]]> + config['templates']['paths']]]> + config['templates']['paths']['ecosystem'][0]]]> + + + + + + + + + + + + + + + + + diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 7b0b4ff3..26eefb2a 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -8,6 +8,7 @@ use DateTimeImmutable; use Exception; use GetLaminas\Ecosystem\CreateEcosystemPackageFromArrayTrait; +use GetLaminas\Ecosystem\EcosystemConnectionTrait; use GetLaminas\Ecosystem\EcosystemPackage; use GetLaminas\Ecosystem\Handler\EcosystemHandler; use GetLaminas\Ecosystem\Mapper\PdoMapper; @@ -18,13 +19,11 @@ use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; +use function array_diff; use function array_key_first; use function assert; -use function base64_decode; use function curl_exec; -use function curl_init; use function curl_setopt; -use function explode; use function file_exists; use function file_get_contents; use function filter_var; @@ -41,30 +40,30 @@ use function uniqid; use function unlink; -use const CURLOPT_FOLLOWLOCATION; -use const CURLOPT_HTTPHEADER; -use const CURLOPT_POST; -use const CURLOPT_POSTFIELDS; -use const CURLOPT_RETURNTRANSFER; use const CURLOPT_URL; use const FILTER_VALIDATE_URL; class CreateEcosystemDatabase extends Command { use CreateEcosystemPackageFromArrayTrait; + use EcosystemConnectionTrait; public const string PACKAGES_DB_PATH = 'data/ecosystem/database'; public const string PACKAGES_DB_FILE = 'packages.db'; private CurlHandle $curl; private CurlHandle $githubCurl; - private ?string $ghToken = null; - private bool $forceRebuild = false; + private ?string $ghToken = null; + private bool $forceRebuild = false; + private array $validPackages = []; public PdoMapper $mapper; /** @var string[] */ private array $indices = [ 'CREATE INDEX keywords ON packages ( keywords )', + 'CREATE INDEX category ON packages ( category )', + 'CREATE INDEX "type" ON packages ( type )', + 'CREATE INDEX "usage" ON packages ( usage )', 'CREATE INDEX package_name ON packages ( name )', ]; @@ -77,7 +76,7 @@ class CreateEcosystemDatabase extends Command %s AS repository, %d AS abandoned, %s AS description, - %s AS usage, + %s AS "usage", %d AS created, %d AS updated, %s AS category, @@ -109,47 +108,6 @@ class CreateEcosystemDatabase extends Command %d, %s'; - private string $searchTable = 'CREATE VIRTUAL TABLE search_packages USING FTS4( - id, - created, - updated, - name, - keywords - )'; - - private string $searchTrigger = 'CREATE TRIGGER after_packages_insert - AFTER INSERT ON packages - BEGIN - INSERT INTO search_packages ( - id, - created, - updated, - name, - keywords - ) - VALUES ( - new.id, - new.created, - new.updated, - new.name, - new.keywords - ); - END - '; - - private string $searchTriggerPostUpdate = 'CREATE TRIGGER after_packages_update - AFTER UPDATE ON packages - BEGIN - UPDATE search_packages - SET - id = new.id, - updated = new.updated, - name = new.name, - keywords = new.keywords - WHERE id = new.id; - END - '; - private string $table = 'CREATE TABLE "packages" ( id VARCHAR(255) NOT NULL PRIMARY KEY, name VARCHAR(255) NOT NULL, @@ -162,7 +120,7 @@ class CreateEcosystemDatabase extends Command created UNSIGNED INTEGER NOT NULL, updated UNSIGNED INTEGER NOT NULL, category VARCHAR(255) NOT NULL, - keywords VARCHAR(255), + keywords TEXT, website VARCHAR(255), downloads UNSIGNED INTEGER, stars UNSIGNED INTEGER, @@ -244,14 +202,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $dbFile = $input->getOption('db-path'); assert(is_string($dbFile)); $this->ghToken = $input->getOption('github-token'); - if (! $this->ghToken) { - $variables = json_decode(base64_decode($_ENV['PLATFORM_VARIABLES']), true); - assert(is_array($variables)); - assert(isset($variables['REPO_TOKEN'])); - - $this->ghToken = $variables['REPO_TOKEN']; - } - assert(is_string($this->ghToken)); $this->forceRebuild = $input->getOption('force-rebuild') !== false; @@ -270,10 +220,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int assert(is_array($userDataArray)); $pdo = $this->createDatabase($dbFile); - $this->initCurl(); - /** @var array{packagistUrl: string, githubUrl: string, categories: array, homepage: string} $userData */ + /** @var array{packagistUrl: string, keywords: array, homepage: string, category: string, usage: string} $userData */ foreach ($userDataArray as $userData) { $curlResult = $this->getPackageData($userData); if ($curlResult === null) { @@ -288,18 +237,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->insertPackageInDatabase($package, $pdo); } + if (! $this->forceRebuild) { + $currentPackages = $this->mapper->getPackagesTitles(); + $removedPackages = array_diff($currentPackages, $this->validPackages); + /** @var string $package */ + foreach ($removedPackages as $package) { + $this->mapper->deletePackageByName($package); + } + } + $io->success('Created ecosystem packages database'); return 0; } - private function createDatabase(string $path): PDO + public function createDatabase(string $path): PDO { if (file_exists($path) && file_get_contents($path) !== '') { if ($this->forceRebuild) { unlink($path); } else { - $path = realpath($path); return new PDO('sqlite:' . $path); } } @@ -315,66 +272,38 @@ private function createDatabase(string $path): PDO foreach ($this->indices as $index) { $pdo->exec($index); } - $pdo->exec($this->searchTable); - $pdo->exec($this->searchTrigger); - $pdo->exec($this->searchTriggerPostUpdate); $pdo->commit(); return $pdo; } - private function initCurl(): void - { - $headers = [ - 'Accept: application/vnd.github+json', - 'X-GitHub-Api-Version: 2022-11-28', - 'User-Agent: getlaminas.org', - ]; - - $this->curl = curl_init(); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); - curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); - - $githubHeaders = [ - 'Accept: application/vnd.github+json', - 'Authorization: Bearer ' . $this->ghToken, - 'X-GitHub-Api-Version: 2022-11-28', - 'User-Agent: getlaminas.org', - ]; - - $this->githubCurl = curl_init(); - curl_setopt($this->githubCurl, CURLOPT_HTTPHEADER, $githubHeaders); - curl_setopt($this->githubCurl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->githubCurl, CURLOPT_RETURNTRANSFER, 1); - } - /** * @phpcs:ignore * @param array{ * packagistUrl: string, - * githubUrl: string, - * keywords: array, - * homepage: string, - * category: string, - * usage: string + * keywords: array, + * homepage: string, + * category: string, + * usage: string * } $userData */ private function getPackageData(array $userData): ?array { - $matches = []; - preg_match('/packagist.org\/packages\/((?>\w-?)+\/(?>\w-?)+)/i', $userData['packagistUrl'], $matches); + $urlComponents = []; + preg_match('/packagist.org\/packages\/((?>\w-?)+\/(?>\w-?)+)/i', $userData['packagistUrl'], $urlComponents); if (! $this->forceRebuild) { - if (! isset($matches[1]) || ! empty($this->mapper->searchPackage($matches[1]))) { + $this->validPackages[] = $urlComponents[1]; + $existingPackage = $this->mapper->searchPackage($urlComponents[1]); + if ($existingPackage !== null && $existingPackage !== []) { return null; } } $packagistUrl = sprintf( 'https://repo.packagist.org/packages/%s.json', - $matches[1] + $urlComponents[1] ); curl_setopt($this->curl, CURLOPT_URL, $packagistUrl); $rawResult = curl_exec($this->curl); @@ -409,14 +338,21 @@ private function getPackageData(array $userData): ?array return null; } - $timestamp = (new DateTimeImmutable())->getTimestamp(); if (! $userData['homepage'] || ! filter_var($userData['homepage'], FILTER_VALIDATE_URL)) { - $lastVersionData = $packageData['versions'][array_key_first($packageData['versions'])]; - $website = $lastVersionData['homepage'] ?? ''; + $lastVersion = array_key_first($packageData['versions']); + if ($lastVersion === null) { + $website = ''; + } else { + $lastVersionData = $packageData['versions'][$lastVersion]; + /** @var array $lastVersionData */ + $website = $lastVersionData['homepage'] ?? ''; + } } else { $website = $userData['homepage']; } + $timestamp = (new DateTimeImmutable())->getTimestamp(); + return [ 'id' => uniqid($packageData['name']), 'name' => $packageData['name'], @@ -434,32 +370,11 @@ private function getPackageData(array $userData): ?array 'keywords' => $userData['keywords'] !== [] ? $userData['keywords'] : '', 'website' => $website, 'image' => $this->getSocialPreview( - str_replace('https://github.com/', '', $packageData['repository']) ?? $matches[1] + str_replace('https://github.com/', '', $packageData['repository']) ), ]; } - private function getSocialPreview(string $package): ?string - { - $packageId = explode('/', $package); - $graphQlUrl = 'https://api.github.com/graphql'; - $graphQlQuery = sprintf( - '{"query": "query {repository(owner: \"%s\", name: \"%s\"){openGraphImageUrl}}"}', - $packageId[0], - $packageId[1] - ); - curl_setopt($this->githubCurl, CURLOPT_URL, $graphQlUrl); - curl_setopt($this->githubCurl, CURLOPT_POST, true); - curl_setopt($this->githubCurl, CURLOPT_POSTFIELDS, $graphQlQuery); - - $rawResult = curl_exec($this->githubCurl); - assert(is_string($rawResult)); - - $githubResult = json_decode($rawResult, true); - - return $githubResult['data']['repository']['openGraphImageUrl'] ?? null; - } - private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): void { $statement = sprintf( @@ -482,9 +397,8 @@ private function insertPackageInDatabase(EcosystemPackage $package, PDO $pdo): v $package->downloads, $package->stars, $package->issues, - $package->image !== null ? $pdo->quote($package->image) : 0, + $pdo->quote($package->image), ); - $pdo->exec($statement); } } diff --git a/src/Ecosystem/Console/SeedEcosystemDatabase.php b/src/Ecosystem/Console/SeedEcosystemDatabase.php index cb5e83da..110c102a 100644 --- a/src/Ecosystem/Console/SeedEcosystemDatabase.php +++ b/src/Ecosystem/Console/SeedEcosystemDatabase.php @@ -6,6 +6,7 @@ use CurlHandle; use DateTimeImmutable; +use GetLaminas\Ecosystem\EcosystemConnectionTrait; use GetLaminas\Ecosystem\Mapper\PdoMapper; use PDO; use Symfony\Component\Console\Command\Command; @@ -15,26 +16,21 @@ use Symfony\Component\Console\Style\SymfonyStyle; use function assert; -use function base64_decode; use function curl_exec; -use function curl_init; use function curl_setopt; -use function explode; use function is_array; use function is_string; use function json_decode; use function realpath; use function sprintf; +use function str_replace; -use const CURLOPT_FOLLOWLOCATION; -use const CURLOPT_HTTPHEADER; -use const CURLOPT_POST; -use const CURLOPT_POSTFIELDS; -use const CURLOPT_RETURNTRANSFER; use const CURLOPT_URL; class SeedEcosystemDatabase extends Command { + use EcosystemConnectionTrait; + public const string PACKAGE_UPDATE_TIME = '6 hours ago'; private CurlHandle $curl; @@ -87,14 +83,6 @@ protected function execute(InputInterface $input, OutputInterface $output): int $dbFile = $input->getOption('db-path'); assert(is_string($dbFile)); $this->ghToken = $input->getOption('github-token'); - if (! $this->ghToken) { - $variables = json_decode(base64_decode($_ENV['PLATFORM_VARIABLES']), true); - assert(is_array($variables)); - assert(isset($variables['REPO_TOKEN'])); - - $this->ghToken = $variables['REPO_TOKEN']; - } - assert(is_string($this->ghToken)); /** @var array{id: string, name: string, updated: int}|null $packagesDueUpdates */ $packagesDueUpdates = $this->mapper->fetchPackagesDueUpdates( @@ -116,7 +104,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int $pdo->beginTransaction(); $this->initCurl(); + /** + * @var array{ + * id: string, + * name: string, + * updated: int + * } $package + */ foreach ($packagesDueUpdates as $package) { + /** + * @phpcs:ignore + * @param array{ + * name: string, + * repository: string, + * abandoned: string, + * description: string, + * updated: int, + * stars: int, + * issues: int, + * downloads: int, + * image: string, + * id: string + * } $packageData + */ $packageData = $this->getPackageData($package); $this->updatePackage($packageData, $pdo); } @@ -128,32 +138,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 0; } - private function initCurl(): void - { - $headers = [ - 'Accept: application/vnd.github+json', - 'X-GitHub-Api-Version: 2022-11-28', - 'User-Agent: getlaminas.org', - ]; - - $this->curl = curl_init(); - curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); - curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); - - $githubHeaders = [ - 'Accept: application/vnd.github+json', - 'Authorization: Bearer ' . $this->ghToken, - 'X-GitHub-Api-Version: 2022-11-28', - 'User-Agent: getlaminas.org', - ]; - - $this->githubCurl = curl_init(); - curl_setopt($this->githubCurl, CURLOPT_HTTPHEADER, $githubHeaders); - curl_setopt($this->githubCurl, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($this->githubCurl, CURLOPT_RETURNTRANSFER, 1); - } - + /** + * @phpcs:ignore + * @param array{ + * id: string, + * name: string, + * updated: int + * } $package + */ private function getPackageData(array $package): array { $packagistUrl = sprintf( @@ -169,14 +161,22 @@ private function getPackageData(array $package): array /** * @var array{ * name: string, + * description: string, + * time: string, + * maintainers: array, + * versions: array, + * type: string, * repository: string, + * github_stars: int, + * github_watchers: int, + * github_forks: int, + * github_open_issues: int, + * language: string, * abandoned: string, - * description: string, - * updated: int, - * stars: int, - * issues: int, + * dependents: int, + * suggesters: int, * downloads: array{total: int, monthly: int, daily: int}, - * id: string + * favers: int * } $packageData */ $packageData = $packagistResult['package']; @@ -187,47 +187,28 @@ private function getPackageData(array $package): array 'abandoned' => (int) isset($packageData['abandoned']), 'description' => $packageData['description'], 'updated' => (new DateTimeImmutable())->getTimestamp(), - 'stars' => (int) $packageData['github_stars'], - 'issues' => (int) $packageData['github_open_issues'], - 'downloads' => (int) $packageData['downloads']['total'], - 'image' => $this->getSocialPreview($packageData['name']), + 'stars' => $packageData['github_stars'], + 'issues' => $packageData['github_open_issues'], + 'downloads' => $packageData['downloads']['total'], + 'image' => $this->getSocialPreview( + str_replace('https://github.com/', '', $packageData['repository']) + ), 'id' => $package['id'], ]; } - private function getSocialPreview(string $package): ?string - { - $packageId = explode('/', $package); - $graphQlQuery = sprintf( - '{"query": "query {repository(owner: \"%s\", name: \"%s\"){openGraphImageUrl}}"}', - $packageId[0], - $packageId[1] - ); - - curl_setopt($this->githubCurl, CURLOPT_URL, 'https://api.github.com/graphql'); - curl_setopt($this->githubCurl, CURLOPT_POST, true); - curl_setopt($this->githubCurl, CURLOPT_POSTFIELDS, $graphQlQuery); - - $rawResult = curl_exec($this->githubCurl); - assert(is_string($rawResult)); - - $githubResult = json_decode($rawResult, true); - - return $githubResult['data']['repository']['openGraphImageUrl'] ?? null; - } - /** * @phpcs:ignore * @param array{ * name: string, * repository: string, - * abandoned: string, + * abandoned: int, * description: string, * updated: int, * stars: int, * issues: int, - * downloads: array{total: int, monthly: int, daily: int}, - * image: string|null + * downloads: int, + * image: string, * id: string * } $packageData */ @@ -243,7 +224,7 @@ private function updatePackage(array $packageData, PDO $pdo): void $packageData['downloads'], $packageData['stars'], $packageData['issues'], - $packageData['image'] !== null ? $pdo->quote($packageData['image']) : '0', + $pdo->quote($packageData['image']), $pdo->quote($packageData['id']) ); diff --git a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php index eec5402d..f2e67194 100644 --- a/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php +++ b/src/Ecosystem/CreateEcosystemPackageFromArrayTrait.php @@ -19,12 +19,12 @@ trait CreateEcosystemPackageFromArrayTrait { /** - * @throws Exception * @phpcs:ignore * @param array{ * id: string, * name: string, * type: string, + * packagistUrl: string, * repository: string, * description: string, * usage: string, @@ -35,28 +35,28 @@ trait CreateEcosystemPackageFromArrayTrait * issues: int, * downloads: int, * abandoned: int, - * packagistUrl: string, * keywords: string|array, * website: string, * license: string, * image: string|null * } $packageData + * @throws Exception */ - private function createEcosystemPackageFromArray(array $packageData): ?EcosystemPackage + protected function createEcosystemPackageFromArray(array $packageData): ?EcosystemPackage { - $created = $this->createDateTimeFromString((string) $packageData['created']); - $updated = $packageData['updated'] && $packageData['updated'] !== $packageData['created'] - ? $this->createDateTimeFromString((string) $packageData['updated']) - : $created; - $category = EcosystemCategoryEnum::tryFrom(trim($packageData['category'])); $type = EcosystemTypeEnum::tryFrom(trim($packageData['type'])); $usage = EcosystemUsageEnum::tryFrom(trim($packageData['usage'])); - if ($category === null) { + if ($category === null || $type === null || $usage === null) { return null; } + $created = $this->createDateTimeFromString((string) $packageData['created']); + $updated = $packageData['updated'] && $packageData['updated'] !== $packageData['created'] + ? $this->createDateTimeFromString((string) $packageData['updated']) + : $created; + return new EcosystemPackage( $packageData['id'], $packageData['name'], @@ -83,7 +83,7 @@ private function createEcosystemPackageFromArray(array $packageData): ?Ecosystem /** * @throws Exception */ - private function createDateTimeFromString(string $dateString): DateTimeImmutable + protected function createDateTimeFromString(string $dateString): DateTimeImmutable { return is_numeric($dateString) ? new DateTimeImmutable('@' . $dateString, new DateTimeZone('America/Chicago')) diff --git a/src/Ecosystem/EcosystemConnectionTrait.php b/src/Ecosystem/EcosystemConnectionTrait.php new file mode 100644 index 00000000..e641d0ab --- /dev/null +++ b/src/Ecosystem/EcosystemConnectionTrait.php @@ -0,0 +1,83 @@ +ghToken === null || $this->ghToken === '') { + $variables = json_decode(base64_decode($_ENV['PLATFORM_VARIABLES']), true); + assert(is_array($variables)); + assert(isset($variables['REPO_TOKEN'])); + + $this->ghToken = $variables['REPO_TOKEN']; + } + assert(is_string($this->ghToken)); + + $headers = [ + 'Accept: application/vnd.github+json', + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: getlaminas.org', + ]; + + $this->curl = curl_init(); + curl_setopt($this->curl, CURLOPT_HTTPHEADER, $headers); + curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, 1); + + $githubHeaders = [ + 'Accept: application/vnd.github+json', + 'Authorization: Bearer ' . $this->ghToken, + 'X-GitHub-Api-Version: 2022-11-28', + 'User-Agent: getlaminas.org', + ]; + + $this->githubCurl = curl_init(); + curl_setopt($this->githubCurl, CURLOPT_HTTPHEADER, $githubHeaders); + curl_setopt($this->githubCurl, CURLOPT_FOLLOWLOCATION, true); + curl_setopt($this->githubCurl, CURLOPT_RETURNTRANSFER, 1); + } + + private function getSocialPreview(string $package): string + { + $packageId = explode('/', $package); + $graphQlQuery = sprintf( + '{"query": "query {repository(owner: \"%s\", name: \"%s\"){openGraphImageUrl}}"}', + $packageId[0], + $packageId[1] + ); + + curl_setopt($this->githubCurl, CURLOPT_URL, 'https://api.github.com/graphql'); + curl_setopt($this->githubCurl, CURLOPT_POST, true); + curl_setopt($this->githubCurl, CURLOPT_POSTFIELDS, $graphQlQuery); + + $rawResult = curl_exec($this->githubCurl); + assert(is_string($rawResult)); + + /** @var array{data: array{repository: array{openGraphImageUrl: string}}} | array{data: array} $githubResult */ + $githubResult = json_decode($rawResult, true); + + return $githubResult['data']['repository']['openGraphImageUrl'] ?? ''; + } +} diff --git a/src/Ecosystem/EcosystemPackage.php b/src/Ecosystem/EcosystemPackage.php index d2ed20af..6b46e28a 100644 --- a/src/Ecosystem/EcosystemPackage.php +++ b/src/Ecosystem/EcosystemPackage.php @@ -11,6 +11,9 @@ class EcosystemPackage { + /** + * @param array $keywords + */ public function __construct( public string $id, public string $name, diff --git a/src/Ecosystem/Handler/EcosystemHandler.php b/src/Ecosystem/Handler/EcosystemHandler.php index 86bae51e..38674f0d 100644 --- a/src/Ecosystem/Handler/EcosystemHandler.php +++ b/src/Ecosystem/Handler/EcosystemHandler.php @@ -23,6 +23,7 @@ use function implode; use function is_array; use function is_string; +use function max; use function sprintf; use function strtolower; @@ -43,13 +44,16 @@ public function handle(ServerRequestInterface $request): ResponseInterface $keywords = $queryParams['keywords'] ?? []; assert(is_array($keywords)); - $type = $queryParams['type'] ?? ''; + $type = $queryParams['type'] ?? ''; + assert(is_string($type)); $type = EcosystemTypeEnum::tryFrom($type)?->name; $category = $queryParams['category'] ?? ''; + assert(is_string($category)); $category = EcosystemCategoryEnum::tryFrom($category)?->name; $usage = $queryParams['usage'] ?? ''; - $usage = EcosystemUsageEnum::tryFrom($usage)?->name; - $search = $queryParams['q'] ?? ''; + assert(is_string($usage)); + $usage = EcosystemUsageEnum::tryFrom($usage)?->name; + $search = $queryParams['q'] ?? ''; assert(is_string($search)); $packages = $this->ecosystemMapper->fetchAllByFilters( @@ -75,7 +79,7 @@ public function handle(ServerRequestInterface $request): ResponseInterface // keep set keyword and search queries if (count($packages) && $page > count($packages)) { $keywordsQuery = ''; - if (! empty($keywords)) { + if ($keywords !== []) { $keywordsQuery = '&keywords[]=' . implode("&keywords[]=", $keywords); } @@ -133,7 +137,7 @@ private function getPageFromRequest(ServerRequestInterface $request): int { $page = $request->getQueryParams()['page'] ?? 1; $page = (int) $page; - return $page < 1 ? 1 : $page; + return max($page, 1); } private function preparePagination(string $path, int $page, object $pagination): object diff --git a/src/Ecosystem/Mapper/MapperInterface.php b/src/Ecosystem/Mapper/MapperInterface.php index 0b75db85..ed2e5ef1 100644 --- a/src/Ecosystem/Mapper/MapperInterface.php +++ b/src/Ecosystem/Mapper/MapperInterface.php @@ -19,7 +19,9 @@ public function fetchAllByFilters(array $filters, string $search = ''): Paginato /** @return Paginator */ public function fetchAllByKeyword(string $keyword): Paginator; - public function search(string $toMatch): ?array; + public function getPackagesTitles(): array; + + public function deletePackageByName(string $package): bool; public function fetchPackagesDueUpdates(DateTimeImmutable $updated): ?array; } diff --git a/src/Ecosystem/Mapper/PdoMapper.php b/src/Ecosystem/Mapper/PdoMapper.php index 3e954818..b5a6e09a 100644 --- a/src/Ecosystem/Mapper/PdoMapper.php +++ b/src/Ecosystem/Mapper/PdoMapper.php @@ -80,14 +80,24 @@ public function fetchAllByKeyword(string $keyword): Paginator return $this->preparePaginator($select, $count, [':tag' => sprintf('%%|%s|%%', $keyword)]); } - public function search(string $toMatch): ?array + public function getPackagesTitles(): array { - $select = $this->pdo->prepare('SELECT id, title from search_packages WHERE search MATCH :query'); - if (! $select->execute([':query' => $toMatch])) { - return null; + $select = $this->pdo->prepare('SELECT name from packages;'); + if (! $select->execute()) { + return []; } - return $select->fetchAll(); + return $select->fetchAll(PDO::FETCH_COLUMN); + } + + public function deletePackageByName(string $package): bool + { + $select = $this->pdo->prepare('DELETE from packages WHERE name = :name;'); + if (! $select->execute([':name' => $package])) { + return false; + } + + return true; } /** diff --git a/src/Ecosystem/Mapper/PdoPaginator.php b/src/Ecosystem/Mapper/PdoPaginator.php index 1e35c7c7..b4f17a54 100644 --- a/src/Ecosystem/Mapper/PdoPaginator.php +++ b/src/Ecosystem/Mapper/PdoPaginator.php @@ -20,9 +20,9 @@ class PdoPaginator implements AdapterInterface { use CreateEcosystemPackageFromArrayTrait; + /** @param array $params */ protected array $params; - /** @param array $params */ public function __construct( protected PDOStatement $select, protected PDOStatement $count, diff --git a/test/Unit/Ecosystem/CommonTestCase.php b/test/Unit/Ecosystem/CommonTestCase.php new file mode 100644 index 00000000..d07784d2 --- /dev/null +++ b/test/Unit/Ecosystem/CommonTestCase.php @@ -0,0 +1,20 @@ +pdo = new PDO('sqlite:' . $this->testDb); + } +} diff --git a/test/Unit/Ecosystem/ConfigProviderTest.php b/test/Unit/Ecosystem/ConfigProviderTest.php new file mode 100644 index 00000000..1e0ca1e3 --- /dev/null +++ b/test/Unit/Ecosystem/ConfigProviderTest.php @@ -0,0 +1,85 @@ +config = (new ConfigProvider())(); + } + + public function testConfigHasKeys(): void + { + $this->assertArrayHasKey('ecosystem', $this->config); + $this->assertArrayHasKey('dependencies', $this->config); + $this->assertArrayHasKey('laminas-cli', $this->config); + $this->assertArrayHasKey('templates', $this->config); + } + + public function testEcosystemHasDb(): void + { + $this->assertArrayHasKey('db', $this->config['ecosystem']); + } + + public function testDependenciesHasFactories(): void + { + $this->assertArrayHasKey('factories', $this->config['dependencies']); + $this->assertIsArray($this->config['dependencies']['factories']); + $this->assertArrayHasKey('config-packages', $this->config['dependencies']['factories']); + $this->assertArrayHasKey(EcosystemHandler::class, $this->config['dependencies']['factories']); + $this->assertArrayHasKey(PdoMapper::class, $this->config['dependencies']['factories']); + } + + public function testDependenciesHasDelegators(): void + { + $this->assertArrayHasKey('delegators', $this->config['dependencies']); + $this->assertIsArray($this->config['dependencies']['delegators']); + $this->assertArrayHasKey(CreateEcosystemDatabase::class, $this->config['dependencies']['delegators']); + $this->assertArrayHasKey(SeedEcosystemDatabase::class, $this->config['dependencies']['delegators']); + } + + public function testDependenciesHasInvokables(): void + { + $this->assertArrayHasKey('invokables', $this->config['dependencies']); + $this->assertIsArray($this->config['dependencies']['invokables']); + $this->assertArrayHasKey(SeedEcosystemDatabase::class, $this->config['dependencies']['invokables']); + $this->assertArrayHasKey(CreateEcosystemDatabase::class, $this->config['dependencies']['invokables']); + } + + public function testCommandsAreRegistered(): void + { + $this->assertArrayHasKey('commands', $this->config['laminas-cli']); + $this->assertContains( + SeedEcosystemDatabase::class, + $this->config['laminas-cli']['commands'] + ); + $this->assertContains( + CreateEcosystemDatabase::class, + $this->config['laminas-cli']['commands'] + ); + } + + public function testGetTemplates(): void + { + $this->assertArrayHasKey('paths', $this->config['templates']); + $this->assertIsArray($this->config['templates']['paths']); + $this->assertArrayHasKey('ecosystem', $this->config['templates']['paths']); + $this->assertDirectoryExists($this->config['templates']['paths']['ecosystem'][0]); + } +} diff --git a/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseDelegatorTest.php b/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseDelegatorTest.php new file mode 100644 index 00000000..74b2dcd2 --- /dev/null +++ b/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseDelegatorTest.php @@ -0,0 +1,49 @@ +createMock(ContainerInterface::class); + $pdoMapper = $this->createMock(PdoMapper::class); + + $container->expects($this->once()) + ->method('get') + ->willReturn($pdoMapper); + + $instance = new CreateEcosystemDatabase(); + + $command = (new CreateEcosystemDatabaseDelegator())( + $container, + '', + function () use ($instance) { + return $instance; + } + ); + + $reflectionMapper = (new ReflectionProperty($command, 'mapper'))->getValue($command); + + $this->assertInstanceOf(PdoMapper::class, $reflectionMapper); + } +} diff --git a/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseTest.php b/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseTest.php new file mode 100644 index 00000000..895ffbb1 --- /dev/null +++ b/test/Unit/Ecosystem/Console/CreateEcosystemDatabaseTest.php @@ -0,0 +1,31 @@ +subject = $this->createMock(CreateEcosystemDatabase::class); + } + + public function testWillCreateDatabase(): void + { + $this->assertInstanceOf(PDO::class, $this->subject->createDatabase( + 'sqlite:' . $this->testDb + )); + } +} diff --git a/test/Unit/Ecosystem/Console/SeedEcosystemDatabaseDelegatorTest.php b/test/Unit/Ecosystem/Console/SeedEcosystemDatabaseDelegatorTest.php new file mode 100644 index 00000000..1fcfbf4f --- /dev/null +++ b/test/Unit/Ecosystem/Console/SeedEcosystemDatabaseDelegatorTest.php @@ -0,0 +1,45 @@ +createMock(ContainerInterface::class); + $pdoMapper = $this->createMock(PdoMapper::class); + + $container->expects($this->once()) + ->method('get') + ->willReturn($pdoMapper); + + $instance = new SeedEcosystemDatabase(); + + $command = (new SeedEcosystemDatabaseDelegator())( + $container, + '', + function () use ($instance) { + return $instance; + } + ); + + $reflectionMapper = (new ReflectionProperty($command, 'mapper'))->getValue($command); + + $this->assertInstanceOf(PdoMapper::class, $reflectionMapper); + } +} diff --git a/test/Unit/Ecosystem/CreateEcosystemPackageFromArrayTraitTest.php b/test/Unit/Ecosystem/CreateEcosystemPackageFromArrayTraitTest.php new file mode 100644 index 00000000..a9351747 --- /dev/null +++ b/test/Unit/Ecosystem/CreateEcosystemPackageFromArrayTraitTest.php @@ -0,0 +1,93 @@ + [[ + 'category' => 'invalid category', + 'type' => EcosystemTypeEnum::Library->value, + 'usage' => EcosystemUsageEnum::Mezzio->value, + ]], + 'invalidTypeArray' => [[ + 'category' => EcosystemCategoryEnum::Integration->value, + 'type' => 'invalid type', + 'usage' => EcosystemUsageEnum::Mezzio->value, + ]], + 'invalidUsageArray' => [[ + 'category' => EcosystemCategoryEnum::Integration->value, + 'type' => EcosystemTypeEnum::Library->value, + 'usage' => 'invalid usage', + ]], + ]; + } + + /** + * @throws Exception + */ + #[DataProvider('failingPackageDataProvider')] + public function testWillNotCreateEcosystemPackageWithInvalidData(array $data): void + { + $this->assertNull($this->createEcosystemPackageFromArray($data)); + } + + /** + * @throws Exception + */ + public function testWillReturnValidObjectWithValidData(): void + { + $package = $this->createEcosystemPackageFromArray([ + 'id' => "uniqueId", + 'name' => "vendorName/packageName", + 'type' => "library", + 'packagistUrl' => "packagistUrl", + 'repository' => "repositoryUrl", + 'description' => "", + 'usage' => "mezzio", + 'created' => 1736408707, + 'updated' => 1736408707, + 'category' => "tool", + 'stars' => 10, + 'issues' => 1, + 'downloads' => 100, + 'abandoned' => 0, + 'keywords' => ['user-defined', 'keywords'], + 'website' => 'user-defined website', + 'license' => 'MIT', + 'image' => '' + ]); + + $this->assertInstanceOf(EcosystemPackage::class, $package); + $this->assertInstanceOf(EcosystemCategoryEnum::class, $package->category); + $this->assertInstanceOf(EcosystemTypeEnum::class, $package->type); + $this->assertInstanceOf(EcosystemUsageEnum::class, $package->usage); + } + + /** + * @throws Exception + */ + public function testWillCreateDateTime(): void + { + $this->assertEquals( + new DateTimeImmutable('01-01-2025'), + $this->createDateTimeFromString('01-01-2025') + ); + } +} diff --git a/test/Unit/Ecosystem/Handler/EcosystemHandlerFactoryTest.php b/test/Unit/Ecosystem/Handler/EcosystemHandlerFactoryTest.php new file mode 100644 index 00000000..33a5dcaf --- /dev/null +++ b/test/Unit/Ecosystem/Handler/EcosystemHandlerFactoryTest.php @@ -0,0 +1,36 @@ +createMock(ContainerInterface::class); + $pdoMapper = $this->createMock(PdoMapper::class); + $renderer = $this->createMock(TemplateRendererInterface::class); + + $container->expects($this->exactly(2)) + ->method('get') + ->willReturnOnConsecutiveCalls($pdoMapper, $renderer); + + $this->assertInstanceOf(EcosystemHandler::class, (new EcosystemHandlerFactory())($container)); + } +} diff --git a/test/Unit/Ecosystem/Mapper/MapperFactoryTest.php b/test/Unit/Ecosystem/Mapper/MapperFactoryTest.php new file mode 100644 index 00000000..e5a9c0f1 --- /dev/null +++ b/test/Unit/Ecosystem/Mapper/MapperFactoryTest.php @@ -0,0 +1,31 @@ +createMock(ContainerInterface::class); + $container->expects($this->once())->method('get')->willReturn([ + 'db' => 'sqlite:' . $this->testDb + ]); + + $this->assertInstanceOf(PdoMapper::class, (new MapperFactory())($container)); + } +} From 5730358c6e05941cd54d542e7cd851ad97737d80 Mon Sep 17 00:00:00 2001 From: Jurj-Bogdan Date: Tue, 14 Jan 2025 14:38:21 +0200 Subject: [PATCH 38/38] missing key added Signed-off-by: Jurj-Bogdan --- src/Ecosystem/Console/CreateEcosystemDatabase.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Ecosystem/Console/CreateEcosystemDatabase.php b/src/Ecosystem/Console/CreateEcosystemDatabase.php index 26eefb2a..eef930c8 100644 --- a/src/Ecosystem/Console/CreateEcosystemDatabase.php +++ b/src/Ecosystem/Console/CreateEcosystemDatabase.php @@ -356,6 +356,7 @@ private function getPackageData(array $userData): ?array return [ 'id' => uniqid($packageData['name']), 'name' => $packageData['name'], + 'type' => $packageData['type'], 'repository' => $packageData['repository'], 'description' => $packageData['description'], 'created' => $timestamp,