Node Swapper is a simple, admin-facing tool that facilitates the otherwise rote job of replacing one node (and all of its requisite aliases and redirects) with another. The use-case is simple: an admin has a popular webpage that they want to replace with a new page without losing traffic or messing with aliases and redirects by-hand. Perhaps the new page uses a new node type, or perhaps the replacement page uses a new UI pattern. Either way, Node Swapper will cut out the guess work and make the swap a success.
The admin need only build the new page, publish it under a temporary alias, and then use Node Swapper, which exists as a UI tool located under Admin > Configuration > System > Node Swapper.
Node Swapper takes care of mapping all the existing page's redirects and aliases to the new node. Before undergoing the swap, admins are presented with a confirmation page that details what exactly Node Swapper will do. Admins also have the option to unpublish the old node and choose a custom suffix to append at the end of the old node's alias.
Adding a suffix onto the old node alias ensures that:
- The old node still lives at a familiar location
- The new node can successfully inherit the old alias
Admins are also free to set a default alias suffix and a default setting for whether to unpublish the old node at Admin > Configuration > System > Node Swapper Settings.
Similar Projects
This project leans heavily on the API from the Redirect and Alias projects and, in a sense, can be thought of as an extension of those existing modules. It doesn't really add any new features to those existing APIs, it just makes the existing ones easier to use for non-technical users, and it makes site management easier for technical users who want to save time.
That said, I don't know of an existing module that does this exact job.
Comments
Comment #2
vishal.kadamComment #3
avpadernoThank you for applying!
Please read Review process for security advisory coverage: What to expect for more details and Security advisory coverage application checklist to understand what reviewers look for. Tips for ensuring a smooth review gives some hints for a smoother review.
The important notes are the following.
To the reviewers
Please read How to review security advisory coverage applications, Application workflow, What to cover in an application review, and Tools to use for reviews.
The important notes are the following.
For new reviewers, I would also suggest to first read In which way the issue queue for coverage applications is different from other project queues.
Comment #4
vishal.kadam1. FILE: README.md
The README file is missing the required sections - Installation and Configuration.
2. FILE: node_swapper.info.yml
Remove "project" and "version" from the info file, it will be added by drupal.org packaging automatically.
Comment #5
abenbowAddressed #4 in 4b7eb528
Comment #6
abenbowComment #7
bbu23The module is missing the
composer.jsonfile.Use dependency injection for loading Path Aliases and Nodes
And actually, you should use ParamConverter in routing file to get node objects directly instead of loading them in the
buildFormmethod. You can get inspired from other node route definitions.In
src/Form/NodeSwapperConfirmForm.phpline 88, the param type for$entity_type_managershould be\Drupal\Core\Entity\EntityTypeManagerInterface, though the__construct()method does not require any function description anymore, so unless you want to keep it, the whole description block can be removed.$src_node->title->valueshould be$src_node->label(), same for destination node.Comment #8
bbu23Comment #9
bbu23And just noticed that your default branch is
main. That should not be the case, it should probably be1.2.xfor your latest tag release.See https://www.drupal.org/docs/develop/git/git-for-drupal-project-maintaine...
Comment #10
abenbowI've made some updates to Node Swapper in accordance with bbu23's requests.
composer.jsonfile with maintainer, support, license, and meta informationNode::LoadandPathAlias::loadcalls and replaced them with dependency injectionConfirmFormclassQuestion: now that the main branch is 1.2.x, should I update this issue's description to include that information?
Comment #11
abenbowComment #12
bbu23Thanks! 👍 Changes look good to me, except for the
inheritdoccomment onNodeSwapperConfirmFormconstructor. It should be completely removed or defined, not inherited (this is super minor).And I also noticed that the config schema defines the
old_node_unpublishas boolean, but the default value from the config install folder is set to integer. It should match the defined type.Changing the status because of the schema issue.
You didn't have the
mainbranch mentioned in the description, so that's up to you. What's important is that the default gitlab branch is set to1.2.xas expected.Comment #13
abenbowThanks for the feedback!
I made some new commits, and this is what is different:
NodeSwapperServiceworks to coerce values into bools, just so it is a little more true to what the configuration is expecting out of the APIComment #14
bbu23Looks good to me!
Let's wait for others / Project Moderator to take a look.
Comment #15
avpadernosrc/Form/NodeSwapperConfirmForm.php
A parent class already defines that property, which does not need to be re-declared.
create()should also call$this->setMessenger()with the messenger service retrieved from the container.$messageneeds to be a translatable string.Comment #16
abenbowResolved the requests in #15 in a new commit: here
Comment #17
avpadernoLet's see if other reviewers report other changes.
Comment #18
avpadernosrc/Form/NodeSwapperConfirmForm.php
Starting with Drupal 10.2, the parent class requires also the
$typedConfigManagerparameter, which also means the project cannot be compatible with all the Drupal 10 releases and Drupal 11. It needs to at least require Drupal 10.2, and pass the required parameter to the parent class's constructor.src/Form/NodeSwapperForm.php
The parent class already defines that property. It also define a method to set it.
src/Form/NodeSwapperSettingsForm.php
With Drupal 10 and Drupal 11, there is no longer need to use
#default_valuefor each form element, when the parent class isConfigFormBase: It is sufficient to use#config_target, as in the following code.Using that code, it is no longer needed to save the configuration values in the form submission handler: The parent class will take care of that.
Comment #19
abenbowI've made some updates in the latest commit that address #18
Unrelated, but I've added a langcode onto the config ymls since Drupal requested that that should be done.
Drupal Core reqs
I've updated the module to require 10.2.x || ^11
src/Form/NodeSwapperConfirmForm.php
So it looks like with regards to the
$typedConfigManagerparameter, that that only applies to instances ofConfigFormBase, at least according to the official notice. Since this is an instance ofConfirmFormBase, I've left it alone.src/Form/NodeSwapperForm.php
I removed the unneeded $configFactory initialization, instead just calling parent::setConfigFactory in the constructor.
src/Form/NodeSwapperSettingsForm.php
I removed the calls to the configFactory when setting a default value, opting instead to use the
#config_targetkey. This meant that I could also drop the submitForm method entirely.Comment #20
avpadernoI apologize: When I added two sentences, I added them in the wrong place and accidently removed the existing sentences. The correct comment was supposed to be the following one.
src/Form/NodeSwapperConfirmForm.php
Some of those properties are already defined from a parent class; they do not need to be defined again. The parent class also defines methods to set those properties; those methods should be used in the constructor.
$configFactory:setConfigFactory()$requestStack:setRequestStack()The documentation for
ConfirmFormBasealso lists the methods to get the value of those properties.src/Form/NodeSwapperForm.php
The parent class already defines that property. It also define a method to set it.
src/Form/NodeSwapperSettingsForm.php
Starting with Drupal 10.2, the parent class requires also the
$typedConfigManagerparameter, which also means the project cannot be compatible with all the Drupal 10 releases and Drupal 11. It needs to at least require Drupal 10.2, and pass the required parameter to the parent class's constructor.With Drupal 10 and Drupal 11, there is no longer need to use
#default_valuefor each form element, when the parent class isConfigFormBase: It is sufficient to use#config_target, as in the following code.Using that code, it is no longer needed to save the configuration values in the form submission handler: The parent class will take care of that.
Yes, the form submission handler is no longer necessary, since the parent class implements it and saves the configuration values basing on the values used for
#config_target.Furthermore, in addition to what reported for the src/Form/NodeSwapperForm.php file, the following code needs to use
configFactory().Comment #21
vishal.kadamI am changing priority as per Issue priorities.
Comment #22
avpadernoThis thread has been idle, in the needs work state with no activity for some months.
May you confirm you are still pursuing this application? If this is the case, and you made commits basing on what previously reported, or you can answer the questions previously asked, please change the status to Needs review.
Comment #23
abenbowHey, my apologies for the delay. I've not had the time to sit down and think through the fixes in #20 yet.
I'm going to schedule some time this week to resolve the most recent requests. Thank you for your patience!
Comment #24
abenbowI've made some new updates to the Node Swapper package.
Both the NodeSwapperConfirmForm and the NodeSwapperSettingsForm use less dependency injection now and instead use parent class methods in order to access the configFactory and the requestStack.
I've also update the composer.json and info file so that the package is using newer dependencies and is prepared for use across 10 and 11.
Here is the source code:
https://git.drupalcode.org/project/node_swapper
Comment #25
rushikesh raval commentedI am changing priority as per Issue priorities.
Comment #26
avpadernosrc/Form/NodeSwapperConfirmForm.php
Code compatible with latest Drupal releases should use property promotion.
Properties are expected to be defined before any method.
Comment #27
avpadernoComment #28
abenbowResolved on this new commit: 4b46cbbb185c2d77c711db65d3c66e560add9c36
Changes:
Comment #29
avpadernosrc/Form/NodeSwapperConfirmForm.php
Code compatible with latest Drupal releases should use property promotion.
The constructor should call
::setConfigFactory(), in the same way it calls::setMessenger(). It should also initialize::$requestStackfor which, unfortunately, the base class does not provide a method.node_swapper.services.yml
Services can be autowired starting with Drupal 9.3.x. This means that it is no longer necessary to give a list of service arguments in the .services.yml file; they will be retrieved from the constructor definition.
Comment #30
vishal.kadamI am changing priority as per Issue priorities.
Comment #31
abenbowI would like to formally close this application. I haven't had the time to work on this that I would have hoped for, so to honor your time, I would like to take the job of reviewing this module off or your plates.
I appreciate the help the reviewers have provided to me during the course of this application. Thank you! And once I have more time, I may apply at some other (as yet undetermined) date.