@amazeelabs/silverback-campaign-urls 1.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/drupal/silverback_campaign_urls/.prettierignore +1 -0
- package/drupal/silverback_campaign_urls/CHANGELOG.md +82 -0
- package/drupal/silverback_campaign_urls/README.md +25 -0
- package/drupal/silverback_campaign_urls/composer.json +8 -0
- package/drupal/silverback_campaign_urls/config/install/system.action.campaign_url_delete_action.yml +13 -0
- package/drupal/silverback_campaign_urls/config/install/views.view.campaign_urls.yml +737 -0
- package/drupal/silverback_campaign_urls/graphql/silverback_campaign_urls.base.graphqls +6 -0
- package/drupal/silverback_campaign_urls/graphql/silverback_campaign_urls.extension.graphqls +0 -0
- package/drupal/silverback_campaign_urls/silverback_campaign_urls.info.yml +10 -0
- package/drupal/silverback_campaign_urls/silverback_campaign_urls.links.action.yml +5 -0
- package/drupal/silverback_campaign_urls/silverback_campaign_urls.links.menu.yml +12 -0
- package/drupal/silverback_campaign_urls/silverback_campaign_urls.permissions.yml +2 -0
- package/drupal/silverback_campaign_urls/silverback_campaign_urls.routing.yml +46 -0
- package/drupal/silverback_campaign_urls/src/CampaignUrlAccessControlHandler.php +29 -0
- package/drupal/silverback_campaign_urls/src/Entity/CampaignUrl.php +179 -0
- package/drupal/silverback_campaign_urls/src/Entity/CampaignUrlInterface.php +34 -0
- package/drupal/silverback_campaign_urls/src/Entity/CampaignUrlListBuilder.php +38 -0
- package/drupal/silverback_campaign_urls/src/Form/CampaignUrlDeleteForm.php +41 -0
- package/drupal/silverback_campaign_urls/src/Form/CampaignUrlDeleteMultipleForm.php +145 -0
- package/drupal/silverback_campaign_urls/src/Form/CampaignUrlForm.php +45 -0
- package/drupal/silverback_campaign_urls/src/Plugin/Action/DeleteCampaignUrl.php +92 -0
- package/drupal/silverback_campaign_urls/src/Plugin/GraphQL/SchemaExtension/SilverbackCampaignUrlSchemaExtension.php +28 -0
- package/drupal/silverback_campaign_urls/src/Plugin/Validation/Constraint/UniqueCampaignUrlSourceConstraint.php +18 -0
- package/drupal/silverback_campaign_urls/src/Plugin/Validation/Constraint/UniqueCampaignUrlSourceConstraintValidator.php +61 -0
- package/drupal/silverback_campaign_urls/tests/src/Kernel/CampaignUrlValidationTest.php +57 -0
- package/package.json +15 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_campaign_urls\Plugin\Action;
|
|
4
|
+
|
|
5
|
+
use Drupal\Core\Action\ActionBase;
|
|
6
|
+
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
|
|
7
|
+
use Drupal\Core\Session\AccountInterface;
|
|
8
|
+
use Drupal\Core\TempStore\PrivateTempStoreFactory;
|
|
9
|
+
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Redirects to a campaign URL deletion form.
|
|
13
|
+
*
|
|
14
|
+
* @Action(
|
|
15
|
+
* id = "campaign_url_delete_action",
|
|
16
|
+
* label = @Translation("Delete campaign URL"),
|
|
17
|
+
* type = "campaign_url",
|
|
18
|
+
* confirm_form_route_name = "entity.campaign_url.multiple_delete_confirm"
|
|
19
|
+
* )
|
|
20
|
+
*/
|
|
21
|
+
class DeleteCampaignUrl extends ActionBase implements ContainerFactoryPluginInterface {
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The tempstore object.
|
|
25
|
+
*
|
|
26
|
+
* @var \Drupal\Core\TempStore\SharedTempStore
|
|
27
|
+
*/
|
|
28
|
+
protected $privateTempStore;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The current user.
|
|
32
|
+
*
|
|
33
|
+
* @var \Drupal\Core\Session\AccountInterface
|
|
34
|
+
*/
|
|
35
|
+
protected $currentUser;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Constructs a new DeleteCampaignUrl object.
|
|
39
|
+
*
|
|
40
|
+
* @param array $configuration
|
|
41
|
+
* A configuration array containing information about the plugin instance.
|
|
42
|
+
* @param string $plugin_id
|
|
43
|
+
* The plugin ID for the plugin instance.
|
|
44
|
+
* @param mixed $plugin_definition
|
|
45
|
+
* The plugin implementation definition.
|
|
46
|
+
* @param \Drupal\Core\TempStore\PrivateTempStoreFactory $temp_store_factory
|
|
47
|
+
* The tempstore factory.
|
|
48
|
+
* @param AccountInterface $current_user
|
|
49
|
+
* Current user.
|
|
50
|
+
*/
|
|
51
|
+
public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
|
|
52
|
+
$this->currentUser = $current_user;
|
|
53
|
+
$this->privateTempStore = $temp_store_factory->get('campaign_url_multiple_delete_confirm');
|
|
54
|
+
|
|
55
|
+
parent::__construct($configuration, $plugin_id, $plugin_definition);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* {@inheritdoc}
|
|
60
|
+
*/
|
|
61
|
+
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
|
|
62
|
+
return new static(
|
|
63
|
+
$configuration,
|
|
64
|
+
$plugin_id,
|
|
65
|
+
$plugin_definition,
|
|
66
|
+
$container->get('tempstore.private'),
|
|
67
|
+
$container->get('current_user')
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* {@inheritdoc}
|
|
73
|
+
*/
|
|
74
|
+
public function executeMultiple(array $entities) {
|
|
75
|
+
$this->privateTempStore->set($this->currentUser->id(), $entities);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* {@inheritdoc}
|
|
80
|
+
*/
|
|
81
|
+
public function execute($object = NULL) {
|
|
82
|
+
$this->executeMultiple([$object]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* {@inheritdoc}
|
|
87
|
+
*/
|
|
88
|
+
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
|
|
89
|
+
return $object->access('delete', $account, $return_as_object);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_campaign_urls\Plugin\GraphQL\SchemaExtension;
|
|
4
|
+
|
|
5
|
+
use Drupal\graphql\GraphQL\ResolverRegistryInterface;
|
|
6
|
+
use Drupal\graphql\Plugin\GraphQL\SchemaExtension\SdlSchemaExtensionPluginBase;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Schema extension plugin that exposes the campaign URLs.
|
|
10
|
+
*
|
|
11
|
+
* @SchemaExtension(
|
|
12
|
+
* id = "silverback_campaign_urls",
|
|
13
|
+
* name = "Silverback Campaign URLs",
|
|
14
|
+
* description = "Schema extension exposing the campaign URLs."
|
|
15
|
+
* )
|
|
16
|
+
*/
|
|
17
|
+
class SilverbackCampaignUrlSchemaExtension extends SdlSchemaExtensionPluginBase {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param ResolverRegistryInterface $registry
|
|
21
|
+
* @return void
|
|
22
|
+
*/
|
|
23
|
+
public function registerResolvers(ResolverRegistryInterface $registry) {
|
|
24
|
+
// No special resolvers to register yet, all the campaign URL fields
|
|
25
|
+
// defined in the extension base graphqls file are resolved using
|
|
26
|
+
// directives.
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_campaign_urls\Plugin\Validation\Constraint;
|
|
4
|
+
|
|
5
|
+
use Symfony\Component\Validator\Constraint;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Validation constraint for unique campaign url source.
|
|
9
|
+
*
|
|
10
|
+
* @Constraint(
|
|
11
|
+
* id = "UniqueCampaignUrlSource",
|
|
12
|
+
* label = @Translation("Unique campaign url source.", context = "Validation"),
|
|
13
|
+
* )
|
|
14
|
+
*/
|
|
15
|
+
class UniqueCampaignUrlSourceConstraint extends Constraint {
|
|
16
|
+
|
|
17
|
+
public $message = 'The campaign url %campaign_url is already in use.';
|
|
18
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\silverback_campaign_urls\Plugin\Validation\Constraint;
|
|
4
|
+
|
|
5
|
+
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
|
|
6
|
+
use Drupal\Core\Entity\EntityTypeManagerInterface;
|
|
7
|
+
use Symfony\Component\DependencyInjection\ContainerInterface;
|
|
8
|
+
use Symfony\Component\Validator\Constraint;
|
|
9
|
+
use Symfony\Component\Validator\ConstraintValidator;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Validates the UniqueCampaignUrlSourceConstraint constraint
|
|
13
|
+
*/
|
|
14
|
+
class UniqueCampaignUrlSourceConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* The entity type manager.
|
|
18
|
+
*
|
|
19
|
+
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
|
|
20
|
+
*/
|
|
21
|
+
protected $entityTypeManager;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Creates a new UniqueCampaignUrlSourceConstraintValidator instance.
|
|
25
|
+
*
|
|
26
|
+
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
|
|
27
|
+
* The entity type manager.
|
|
28
|
+
*/
|
|
29
|
+
public function __construct(EntityTypeManagerInterface $entity_type_manager) {
|
|
30
|
+
$this->entityTypeManager = $entity_type_manager;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* {@inheritdoc}
|
|
35
|
+
*/
|
|
36
|
+
public static function create(ContainerInterface $container) {
|
|
37
|
+
return new static(
|
|
38
|
+
$container->get('entity_type.manager')
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* {@inheritDoc}
|
|
44
|
+
*/
|
|
45
|
+
public function validate($entity, Constraint $constraint) {
|
|
46
|
+
/** @var \Drupal\silverback_campaign_urls\Entity\CampaignUrlInterface $entity */
|
|
47
|
+
$source = $entity->getSource();
|
|
48
|
+
$query = $this->entityTypeManager->getStorage('campaign_url')->getQuery();
|
|
49
|
+
$query->condition('campaign_url_source', $source);
|
|
50
|
+
if (!$entity->isNew()) {
|
|
51
|
+
$query->condition('cid', $entity->id(), '<>');
|
|
52
|
+
}
|
|
53
|
+
$query->accessCheck(FALSE);
|
|
54
|
+
$result = $query->execute();
|
|
55
|
+
if (!empty($result)) {
|
|
56
|
+
$this->context->buildViolation($constraint->message, [
|
|
57
|
+
'%campaign_url' => $source,
|
|
58
|
+
])->addViolation();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
|
|
3
|
+
namespace Drupal\Tests\silverback_campaign_urls\Kernel;
|
|
4
|
+
|
|
5
|
+
use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
|
|
6
|
+
use Drupal\silverback_campaign_urls\Entity\CampaignUrl;
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Tests campaign urls validation constraints.
|
|
10
|
+
*/
|
|
11
|
+
class CampaignUrlValidationTest extends EntityKernelTestBase {
|
|
12
|
+
|
|
13
|
+
protected static $modules = ['silverback_campaign_urls'];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* {@inheritDoc}
|
|
17
|
+
*/
|
|
18
|
+
protected function setUp(): void {
|
|
19
|
+
parent::setUp();
|
|
20
|
+
$this->installEntitySchema('campaign_url');
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
public function testValidation() {
|
|
24
|
+
$campaign = CampaignUrl::create([
|
|
25
|
+
'campaign_url_source' => '/campaign_test',
|
|
26
|
+
'campaign_url_destination' => '/campaign_destination',
|
|
27
|
+
]);
|
|
28
|
+
$violations = $campaign->validate();
|
|
29
|
+
$this->assertCount(0, $violations, 'No violations when validating the first campaign url.');
|
|
30
|
+
$campaign->save();
|
|
31
|
+
|
|
32
|
+
$secondCampaign = CampaignUrl::create([
|
|
33
|
+
'campaign_url_source' => '/second_campaign_test',
|
|
34
|
+
'campaign_url_destination' => '/second_campaign_destination',
|
|
35
|
+
]);
|
|
36
|
+
$violations = $secondCampaign->validate();
|
|
37
|
+
$this->assertCount(0, $violations, 'No violations when validating the second campaign url.');
|
|
38
|
+
$secondCampaign->save();
|
|
39
|
+
|
|
40
|
+
$thirdCampaign = CampaignUrl::create([
|
|
41
|
+
'campaign_url_source' => '/campaign_test',
|
|
42
|
+
'campaign_url_destination' => '/third_campaign_destination',
|
|
43
|
+
]);
|
|
44
|
+
$violations = $thirdCampaign->validate();
|
|
45
|
+
$this->assertCount(1, $violations, 'Violation found when trying to create a campaign with an already existing source.');
|
|
46
|
+
$this->assertEquals('The campaign url <em class="placeholder">/campaign_test</em> is already in use.', $violations[0]->getMessage());
|
|
47
|
+
|
|
48
|
+
$existingCampaign = CampaignUrl::load($campaign->id());
|
|
49
|
+
$violations = $existingCampaign->validate();
|
|
50
|
+
$this->assertCount(0, $violations, 'No violations when editing a campaign and keeping its source.');
|
|
51
|
+
|
|
52
|
+
$existingCampaign->set('campaign_url_source', '/second_campaign_test');
|
|
53
|
+
$violations = $existingCampaign->validate();
|
|
54
|
+
$this->assertCount(1, $violations, 'Violation found when trying to update a campaign with an already existing source.');
|
|
55
|
+
$this->assertEquals('The campaign url <em class="placeholder">/second_campaign_test</em> is already in use.', $violations[0]->getMessage());
|
|
56
|
+
}
|
|
57
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@amazeelabs/silverback-campaign-urls",
|
|
3
|
+
"version": "1.0.10",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"precommit": "pnpm precommit:fix && pnpm precommit:check && pnpm test:unit",
|
|
6
|
+
"precommit:fix": "pnpm --filter @custom/cms precommit:fix packages/@amazeelabs/silverback-campaign-urls/drupal",
|
|
7
|
+
"precommit:check": "pnpm --filter @custom/cms precommit:check packages/@amazeelabs/silverback-campaign-urls/drupal",
|
|
8
|
+
"test:unit": "pnpm --filter @custom/cms cms:test:unit --filter=silverback_campaign_urls",
|
|
9
|
+
"test:integration": "pnpm --filter @custom/cms cms:test:integration --filter=silverback_campaign_urls"
|
|
10
|
+
},
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"access": "public"
|
|
13
|
+
},
|
|
14
|
+
"gitHead": "8e0638f5452e77742f99aebe4a65606aac751103"
|
|
15
|
+
}
|