Repository

8.x-4.x branch in Git

Original intro

Drupal 8 is now in its second beta. API changes are still happening, but it should be fine to start converting modules now.

First, I have to clean up Drupal 7 to get it into a state ready for porting. If I postpone this cleanup to Drupal 8, it will probably be much harder.

There are many features I wanted to get into Drupal 7 but did not have time to do, and I didn't receive any patches that added these. Hopefully, these will be easier in Drupal 8 or will at least follow more standardized patterns (making FillPDF templates into entities, filling with data from any entity and not just nodes/webforms, etc.).

(edit: Yep! I've done both of those so far! Wasn't able to dump the query string from the URL format, though.)

Goal

Launch a full Drupal 8 version. (pretty much achieved; touch-ups remain)

Original Goal

Launch a Drupal 8 version that has approximate feature parity with Drupal 7; no new features, no new Drupal APIs (conceptually, since obviously the APIs have changed) used. This will be 8.x-3.x.

Remaining tasks

- Fix FillPdfFormFieldForm (edit PDF field mapping form) forms to look like D7 version
- Fix display of token tree (see #2473259: Token tree is not a tree)
- Fix file usage for FillPdfForm entity (no need to add it manually; the file field actually does this). Implement proper entity access controller and use it for entity forms.
- Same thing re. entity access for FillPdfFormField. Right now the routes are using a custom access controller (which in itself could probably be made into a base class or repurposed somehow).
- Complete HandlePdfController::populatePdf()

  • actually use token-to-PDF field mappings
  • implement real access checking
  • make post-generation action plugins as well (sending to user's browser, saving, saving and redirecting to, etc.). These would just return a Response (or RedirectResponse, etc.) to the controller.
  • support saving result to file — and: - Forward-port private files support recently added to Drupal 7, since it's kinda silly to re-iterate on this later
  • support redirecting to result
  • transform values
  • prefix/suffix

- Make token replacement work better when there are multiple tokens in the same string and multiple input sources. See @todo in-module. This should be the same logic for tokens in the title. And should probably be a utility function eventually (just make it a controller helper for now).
- Convert field mapping import/export form
- Allow updating the PDF (similar logic to export/import)
- Fill from the default entity.
- Add rest of FillPdfForm fields (transformations, etc.)
- Implement fillpdf_backend plugins for JavaBridge and pdftk
- Ensure module works with dynamic_page_cache: https://www.drupal.org/documentation/modules/dynamic_page_cache
- Delete legacy code and files

Roadmap, but not necessarily first version

- Check code with Coder Review #2624090: Fix Coder violations for Drupal ruleset.
- TESTS TESTS TESTS. For access checking, PDF generation, the various FillPdfForm/FillPdfFormField settings, etc. #1393056: [Meta] Write tests
- Figure out how to show actual file locations for private, uploaded PDFs shown using the file field in the fillpdf_forms view. #2624120: Show actual file locations in FillPDF Forms view
- Create a class to hold FillPdfLinkContext information. This will replace the job of the $context array because I can make an interface and document it, then point people there instead of telling them to look at FillPdfManipulator::parseLink(). #2624122: Create ValueObject-pattern class to replace $context array
- Add check for xmlrpc module (moved to contrib in D8) to FillPdfSettingsForm — the overview page already has one #2624138: Add ModuleHandler::moduleExists() check for xmlrpc to FillPdfSettingsForm
- Rename classes to be less redundant, e.g. DownloadAction vs. FillPdfDownloadAction, etc. They're already namespaced. Ref: https://www.drupal.org/node/608152#naming #2624144: Revisit naming convention for classes
- Refactor \Drupal\fillpdf\Controller\HandlePdfController to contain less original logic. It should almost exclusively use services. Note: This is related to having a canonical FillPdfForm route. #2624156: Move all original logic in HandlePdfController into services
- Integrate with D8 Rules #2624162: Rules integration (D8)
- FillPdfForm field type (@FieldType) for entities, maybe themeable as a button or link #2343507: FillPDF field

Follow-up

Port the Drupal 8 version to use Drupal 8 concepts more correctly. I don't know what those are, yet, so I'm not going to open follow-up issues until I'm farther along here. Actually, I pretty much had to do this, so I'm just going to use this section for roadmap stuff that I don't wind up getting done.

Want to help?

Leave a comment here :)

Comments

wizonesolutions’s picture

I went way farther on this than anticipated. Anyway, I'm opening a GitHub repository shortly so I can work openly on this. The GitHub repository is temporary; if you just want to use the stable Drupal 7 version of the module, you should download it from Drupal.org.

Repository: https://github.com/wizonesolutions/fillpdf

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Just an update several months later; still working on this, and it's not as blocked by #2359209 as I thought. I'll be continuing to work on this gradually and might even have an almost-release by the time D8 comes out...but that's far from a promise. My main purpose doing the port is to learn D8. But that doesn't mean the code won't be usable.

wizonesolutions’s picture

Title: Port FillPDF and submodules to initial Drupal 8 version » #D8CX: I pledge that FillPDF will have a full Drupal 8 release on the day that Drupal 8 is released.
Issue summary: View changes
Issue tags: -DrupalCamp Oslo 2014 +DrupalCon Barcelona 2015, +Needs issue summary update

Changing title to join #d8cx.

wizonesolutions’s picture

Issue summary: View changes

Moving module tasks from my to-do app to the issue summary.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes

  • wizonesolutions committed 0c243a9 on 8.x-4.x
    Issue #2359213: Revert "Revert "Issue #2539213: Flesh out FillPdfForm...
  • wizonesolutions committed f1f1d2a on 8.x-4.x
    Issue #2359213: Revert "Revert "Add use statement for annotation class...
wizonesolutions’s picture

Version: 7.x-1.x-dev » 8.x-4.x-dev
wizonesolutions’s picture

Issue summary: View changes

wizonesolutions’s picture

Issue summary: View changes

Yay, token replacement is working with real tokens and the new entity-based FillPDF Link format. Not everything's perfect, but it works the same way as Drupal 7 (including how it doesn't always handle multiple tokens from different sources in the same fill pattern well yet).

wizonesolutions’s picture

Issue summary: View changes

wizonesolutions’s picture

Issue summary: View changes

Access checking done! Next: saving to file.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Strategy to port saving to file, etc.:

- Add configuration for fillpdf.scheme to FillPdfAdminForm
- Add configuration for saved-file scheme to FillPdfFormField/FillPdfFormForm
- Port file scheme support for uploading PDF form (save path for the template)
- Enforce that file is subdirectory fillpdf/ prefix in saved file paths
- Port file saving from Drupal 7 (the latest 7.x-1.x code) — including private file support
- Port redirecting

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Brain freeze on porting file saving, so writing out my thoughts:

Drupal 7 implementation:

- Determine $action: 'default' by default, which uses the PDF form settings to determine what to do. This is already ported to Drupal 8.
- Actually save the file. To do this, we pass the PDF metadata, a filename, and whether to redirect/redirect to the file/override the destination directory.
- We process those arguments, particularly destination path — we run that through token_replace.
- We ensure the destination directory exists. We error out if it doesn't, or well — do nothing and log it.
- If we're all good, then we save the file and add usage data (including the generation context). We return the file.

Drupal 8 implementation ideas:
- Determine $action in the same way.
- Create a standalone FillPdfGenerationContext class that will play the role of D7's $fillpdf_object (stdClass in D8 is icky)
- Instantiate one, and pass the other arguments as they are now. $destination_path_override might not be needed, since a third-party caller could just mess with the FillPdfGenerationContext.
- Still process tokens in the destination path and ensure it exists
- Save the file, add file usage in the same way
-- Challenge: Currently, I use a $fillpdf_context (the passed-in $context) to determine which entities the PDF references and check access accordingly. I store that in a database table and the use the ID of the record in the file usage entry. This is no problem in D8, but I'm not sure if it should be a ContentEntity or not. It seems excessive to use a ContentEntity since it has no UI, but I want to ask around first.
- Return the file, and in the parent function return the appropriate RedirectResponse.

wizonesolutions’s picture

Also, considering a FillPdfActions standalone class. Main initial function would just be to provide a standard way to save to file. I think a service would be overkill because there isn't that much to inject. Well, I do log an error if the path doesn't exist...so I guess it would be a service. Anyway, yeah. Should be reusable. But not to the point of being a plugin or anything...yet. That's actually a future idea, since it would let people do stuff with PDF results that I haven't thought about. But they have other ways to do that for now.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes

Decided to implement action plugins now. Bite-size chunks are easier for me to wrap my head around.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Alright, finally got action plugins wired up! Now I can finish porting file saving, and the length of HandlePdfController::handlePopulatedPdf() won't drive me crazy anymore. Need to make a service that actually handles saving the PDF (so that other modules can do it independently). I might move some of the logic for doing stuff to PDFs generally into that service; the controller shouldn't be the owner of so much functionality. Well, one thing at a time. I also want to turn most of the options arrays into objects, but I'm not going to get held up on that.

wizonesolutions’s picture

Issue summary: View changes

Realized I've named a lot of things redundantly, so added that to the roadmap. Also, I figured out an easy solution to fixing token replacement (which I should backport to D7): http://drupal.stackexchange.com/questions/177891/most-efficient-way-to-r... (replacing them in reverse order, progressively).

  • wizonesolutions committed ceb8804 on 8.x-4.x
    Issue #2359213: WIP Implement file saving.
    
    The saving part is almost...
wizonesolutions’s picture

Made some decent progress this weekend. There's much re-architecting going on, and this slows things down, but there's no way around it. Most of the hard-hitting features are in or ready to be added pretty easily, though. Some major remaining parts are import/export of mappings (actually, I'd like to upgrade this to import/export of entire FillPdfForm records + FillPdfFormField mappings, substitutions (transformations), updating the PDF, and redirecting to the PDF.

Also...tests.

wizonesolutions’s picture

Issue summary: View changes

  • wizonesolutions committed 611287f on 8.x-4.x
    Issue #2359213: WIP Attach generated files to FillPdfFileContext.
    
    And a...
  • wizonesolutions committed 84e5bbf on 8.x-4.x
    Issue #2359213: WIP Switch entity_reference fields to file fields.
    
    I've...
  • wizonesolutions committed 84ec5ea on 8.x-4.x
    Issue #2359213: Remove parseRequest from FillPdfLinkManipulatorInterface...

wizonesolutions’s picture

Finally using file fields instead of entity references for files. While I'm in this mode, I'm going to go through and write proper entity access classes for the entity types I define and make the forms use these.

PDF generation, due to its nature (being a link not clearly-connected to any form or route), will still use FillPdfAccessController::checkLink()...at least, I think it will. I have to separate the access-checking functionality out into a service that takes a $context and tells me if access is granted. I need that for FillPdfFileContextAccessControlHandler::checkAccess(), which basically does the exact same thing, just with FillPdfLinkManipulator::parseLink()(instead of ::parseRequest(), and it uses the fillpdf_file_context.context field.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

File saving and handling of private files is DONE! There are general tweaks to be made that will affect this, but the functionality itself is working.

I also updated the issue summary. i haven't written it there, but I've written up a timeline in my own notes, and I think I can get this done during DrupalCamp Oslo (Nov 14 or 15). If so, I'll release an rc1. So if you are watching this issue, keep an eye out for that! (I'll tweet and such.)

  • wizonesolutions committed 36fcef6 on 8.x-4.x
    Issue #2359213: Check access for private files.
    
    A few things happened...
wizonesolutions’s picture

Issue summary: View changes

Adding a real FillPdfLinkContext object to roadmap.

wizonesolutions’s picture

Huh, switching to file fields broke my fillpdf_forms view. Need to look into this and see if I can format it as a file URI again somehow. Maybe there's some other widget I can use somehow in contrib.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue tags: +DrupalCamp Oslo 2015
wizonesolutions’s picture

Issue summary: View changes

Updating remaining action items. Getting there!

wizonesolutions’s picture

If you didn't notice, there's an alpha out now. See the project page if you want to try it out. I'll be continuing to work on it and move towards making it feature-complete according to the must-port features in the issue summary.

wizonesolutions’s picture

Issue summary: View changes

  • wizonesolutions committed 04cd26a on 8.x-4.x
    Issue #2359213: Normalized token replacement.
    
    Turns out tokens don't...
  • wizonesolutions committed 0d4dcc5 on 8.x-4.x
    Issue #2359213: Add fillpdf.token_resolver.
    
    And update the feature...

  • wizonesolutions committed e07ea8c on 8.x-4.x
    Issue #2359213: Port value-replacement (transforms).
    
    Snuck in a couple...

wizonesolutions’s picture

Issue summary: View changes
Status: Active » Needs work

Hi, I'm at a Drupal 8 release party in Trondheim. During the party, I finished the module. Time to release!

Symbolically changing to Needs Work because I need to open follow-up issues.

#D8CX promise: FULFILLED.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes

  • wizonesolutions committed a749440 on 2359213-cleanup
    Issue #2359213: Make PDF-populating defaults work.
    
  • wizonesolutions committed b283f1c on 2359213-cleanup
    Issue #2359213: Fix default PDF link replacements.
    
    And some code style.
    
  • wizonesolutions committed ef5b350 on 2359213-cleanup
    Issue #2359213: Add import/export links to form.
    

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Abandoning Coder fixing until I figure out #2624076: Support namespace aliases in /** @var */ definitions or it's resolved.

wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes
wizonesolutions’s picture

Issue summary: View changes
Status: Needs work » Fixed

Follow-ups created. See you there!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

quietone’s picture