Skip to content

Commit 63eb781

Browse files
committed
add tags plugin + adjust sync + add tags to template + add filter for tags
1 parent 63ba50e commit 63eb781

7 files changed

Lines changed: 217 additions & 19 deletions

File tree

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"cakephp/cakephp": "5.2.*",
1010
"cakephp/migrations": "^4.0.0",
1111
"cakephp/plugin-installer": "^2.0",
12+
"dereuromark/cakephp-tags": "^2.2",
1213
"friendsofcake/search": "^7.5",
1314
"knplabs/packagist-api": "^2.1",
1415
"mobiledetect/mobiledetectlib": "^4.8.03"

composer.lock

Lines changed: 73 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/plugins.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@
3434

3535
// Additional plugins here
3636
'Search',
37+
'Tags',
3738
];

src/Command/SyncPackagesCommand.php

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,19 @@
55

66
use Cake\Command\Command;
77
use Cake\Console\Arguments;
8+
use Cake\Console\CommandFactoryInterface;
89
use Cake\Console\ConsoleIo;
910
use Cake\Log\Log;
11+
use Composer\Semver\Semver;
1012
use Packagist\Api\Client;
1113

1214
/**
1315
* SyncPackages command.
1416
*/
1517
class SyncPackagesCommand extends Command
1618
{
19+
private Client $client;
20+
1721
/**
1822
* The name of this command.
1923
*
@@ -41,6 +45,16 @@ public static function getDescription(): string
4145
return 'Command description here.';
4246
}
4347

48+
/**
49+
* @param \Cake\Console\CommandFactoryInterface|null $factory
50+
*/
51+
public function __construct(
52+
?CommandFactoryInterface $factory = null,
53+
) {
54+
parent::__construct($factory);
55+
$this->client = new Client();
56+
}
57+
4458
/**
4559
* Implement this method with your command's logic.
4660
*
@@ -50,18 +64,19 @@ public static function getDescription(): string
5064
*/
5165
public function execute(Arguments $args, ConsoleIo $io)
5266
{
53-
$client = new Client();
5467
$packagesTable = $this->fetchTable('Packages');
5568

5669
/** @var \Packagist\Api\Result\Result $package */
57-
foreach ($client->search('', ['type' => 'cakephp-plugin']) as $package) {
70+
foreach ($this->client->search('', ['type' => 'cakephp-plugin']) as $package) {
71+
$tags = $this->getTagsForPackage($package->getName());
5872
$data = [
5973
'package' => $package->getName(),
6074
'description' => $package->getDescription(),
6175
'repo_url' => $package->getRepository(),
6276
'packagist_url' => $package->getUrl(),
6377
'downloads' => $package->getDownloads(),
6478
'stars' => $package->getFavers(),
79+
'tag_list' => $tags,
6580
];
6681

6782
$entity = $packagesTable->find()->where(['package' => $package->getName()])->first();
@@ -78,4 +93,84 @@ public function execute(Arguments $args, ConsoleIo $io)
7893
}
7994
}
8095
}
96+
97+
/**
98+
* @param string $packageName
99+
* @return array
100+
*/
101+
private function getTagsForPackage(string $packageName): array
102+
{
103+
$metaDetails = $this->client->getComposer($packageName);
104+
105+
/** @var \Packagist\Api\Result\Package $metaDetails */
106+
$metaDetails = $metaDetails[$packageName];
107+
$versions = $metaDetails->getVersions();
108+
109+
$meta = [];
110+
// Check each version
111+
foreach ($versions as $versionMeta) {
112+
$phpRequire = $versionMeta->getRequire()['php'] ?? null;
113+
if ($phpRequire) {
114+
$meta = $this->checkPHPVersion($meta, $phpRequire);
115+
}
116+
117+
$cakephpRequire = $versionMeta->getRequire()['cakephp/cakephp'] ?? null;
118+
if ($cakephpRequire) {
119+
$meta = $this->checkCakeVersion($meta, $cakephpRequire);
120+
}
121+
}
122+
123+
return $meta;
124+
}
125+
126+
/**
127+
* @param array $meta
128+
* @param string $packageConstraint
129+
* @return array
130+
*/
131+
private function checkPHPVersion(array $meta, string $packageConstraint): array
132+
{
133+
$phpVersions = [
134+
'8.4.0' => 'PHP: 8.4',
135+
'8.3.0' => 'PHP: 8.3',
136+
'8.2.0' => 'PHP: 8.2',
137+
'8.1.0' => 'PHP: 8.1',
138+
'8.0.0' => 'PHP: 8.0',
139+
'7.4.0' => 'PHP: 7.4',
140+
'7.3.0' => 'PHP: 7.3',
141+
'7.2.0' => 'PHP: 7.2',
142+
'7.1.0' => 'PHP: 7.1',
143+
'7.0.0' => 'PHP: 7.0',
144+
];
145+
146+
foreach ($phpVersions as $version => $label) {
147+
if (Semver::satisfies($version, $packageConstraint) && !in_array($label, $meta)) {
148+
$meta[] = $label;
149+
}
150+
}
151+
152+
return $meta;
153+
}
154+
155+
/**
156+
* @param array $meta
157+
* @param string $packageConstraint
158+
* @return array
159+
*/
160+
private function checkCakeVersion(array $meta, string $packageConstraint): array
161+
{
162+
$cakeVersions = [
163+
'5.0.0' => 'CakePHP: 5.0',
164+
'4.0.0' => 'CakePHP: 4.0',
165+
'3.0.0' => 'CakePHP: 3.0',
166+
];
167+
168+
foreach ($cakeVersions as $version => $label) {
169+
if (Semver::satisfies($version, $packageConstraint) && !in_array($label, $meta)) {
170+
$meta[] = $label;
171+
}
172+
}
173+
174+
return $meta;
175+
}
81176
}

src/Controller/PackagesController.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ class PackagesController extends AppController
1818
public function index()
1919
{
2020
$query = $this->Packages
21-
->find('search', search: $this->request->getQueryParams());
21+
->find('search', search: $this->request->getQueryParams())
22+
->contain(['Tags']);
2223
$packages = $this->paginate($query);
2324

24-
$this->set(compact('packages'));
25+
$tags = $this->Packages->Tags->find('list', ...['keyField' => 'slug']);
26+
27+
$this->set(compact('packages', 'tags'));
2528
}
2629
}

src/Model/Table/PackagesTable.php

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace App\Model\Table;
55

6+
use Cake\ORM\Query\SelectQuery;
67
use Cake\ORM\Table;
78
use Cake\Validation\Validator;
89
use Search\Manager;
@@ -41,6 +42,7 @@ public function initialize(array $config): void
4142
$this->setPrimaryKey('id');
4243

4344
$this->addBehavior('Search.Search');
45+
$this->addBehavior('Tags.Tag', ['taggedCounter' => false]);
4446
}
4547

4648
/**
@@ -95,15 +97,22 @@ public function searchManager(): Manager
9597
/** @var \Search\Model\Behavior\SearchBehavior $search */
9698
$search = $this->getBehavior('Search');
9799
$searchManager = $search->searchManager();
98-
$searchManager->add('search', 'Search.Like', [
99-
'before' => true,
100-
'after' => true,
101-
'fieldMode' => 'OR',
102-
'comparison' => 'LIKE',
103-
'wildcardAny' => '*',
104-
'wildcardOne' => '?',
105-
'fields' => ['package', 'description'],
106-
]);
100+
$searchManager
101+
->add('search', 'Search.Like', [
102+
'before' => true,
103+
'after' => true,
104+
'fieldMode' => 'OR',
105+
'comparison' => 'LIKE',
106+
'wildcardAny' => '*',
107+
'wildcardOne' => '?',
108+
'fields' => ['package', 'description'],
109+
])
110+
->callback('slug', [
111+
'callback' => function (SelectQuery $query, array $args, $manager): void {
112+
// Here you would have to remap $args if key isn't the expected "tag"
113+
$query->find('tagged', ...$args);
114+
},
115+
]);
107116

108117
return $searchManager;
109118
}

templates/Packages/index.php

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/**
33
* @var \App\View\AppView $this
44
* @var iterable<\App\Model\Entity\Package> $packages
5+
* @var iterable<\Tags\Model\Entity\Tag> $tags
56
*/
67
?>
78
<div class="packages index content">
@@ -11,6 +12,12 @@
1112
<?php
1213
echo $this->Form->create(null, ['valueSources' => 'query', 'class' => 'flex gap-4']);
1314
echo $this->Form->control('search', ['label' => false,]);
15+
echo $this->Form->control('slug', [
16+
'label' => false,
17+
'options' => $tags,
18+
'empty' => __('No Filter'),
19+
'multiple' => true,
20+
]);
1421
echo $this->Form->button('Search', ['type' => 'submit']);
1522
echo $this->Form->end();
1623
?>
@@ -25,11 +32,21 @@
2532

2633
<div class="grid grid-cols-4 gap-4">
2734
<?php foreach ($packages as $package): ?>
28-
<div class="border-2 rounded-2xl border-black p-4">
29-
<div class="text-center text-xl mb-2"><?= h($package->package) ?></div>
30-
<div class="flex justify-center gap-4 mb-4">
31-
<a class="underline" target="_blank" href="<?= $package->repo_url ?>"><?= __('Repository') ?></a>
32-
<a class="underline" target="_blank" href="<?= $package->packagist_url ?>"><?= __('Packagist') ?></a>
35+
<div class="border-2 rounded-2xl border-black p-4 flex flex-col justify-between">
36+
<div>
37+
<div class="text-center text-xl mb-2"><?= h($package->package) ?></div>
38+
<div class="flex justify-center gap-4 mb-4">
39+
<a class="underline" target="_blank" href="<?= $package->repo_url ?>"><?= __('Repository') ?></a>
40+
<a class="underline" target="_blank" href="<?= $package->packagist_url ?>"><?= __('Packagist') ?></a>
41+
</div>
42+
</div>
43+
<div class="flex flex-wrap gap-2 mb-4">
44+
<?php foreach($package->tags as $tag): ?>
45+
<a href="?slug=<?= $tag->slug ?>" class="text-xs rounded-3xl px-2 py-1 text-white
46+
<?= str_starts_with($tag->label, 'PHP') ? 'bg-blue-400' : 'bg-red-500' ?>">
47+
<?= $tag->label ?>
48+
</a>
49+
<?php endforeach; ?>
3350
</div>
3451
<div class="flex justify-between [&_svg]:w-6">
3552
<div class="flex gap-2">

0 commit comments

Comments
 (0)