PDF Injector is a REDCap module that enables you to populate fillable PDFs with record data from variables.
Pull Requests are welcome. When opening a Pull Request please add a new Branch.
Run tests
vendor\bin\phpunit
Ekin Tertemiz
PDF Injector is a REDCap module that enables you to populate fillable PDFs with record data from variables.
Home Page: https://research-it-swiss-tph.github.io/redcap-pdf-injector/
License: MIT License
PDF Injector is a REDCap module that enables you to populate fillable PDFs with record data from variables.
Pull Requests are welcome. When opening a Pull Request please add a new Branch.
Run tests
vendor\bin\phpunit
Ekin Tertemiz
When trying a batch download (through REDCap reports), there will be an error in following scenario:
Full Error Message:
Fatal error: Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, bool given in \www\redcap\modules\pdf_injector_v2.2.0\batch.php:123 Stack trace: #0 \www\redcap\modules\pdf_injector_v2.2.0\batch.php(123): fwrite(false, '%PDF-1.6\n%\xE2\xE3\xCF\xD3\n...') #1 \www\redcap\redcap_v12.4.26\ExternalModules\index.php(126): require('C:\\laragon\\www\\...') #2 {main} thrown in \www\redcap\modules\pdf_injector_v2.2.0\batch.php on line 123
REDCap crashed due to an unexpected PHP fatal error!
Error message: Uncaught TypeError: fwrite(): Argument #1 ($stream) must be of type resource, bool given in modules\pdf_injector_v2.2.0\batch.php:123 Stack trace: #0 modules\pdf_injector_v2.2.0\batch.php(123): fwrite(false, '%PDF-1.6\n%\xE2\xE3\xCF\xD3\n...') #1 redcap_v12.4.26\ExternalModules\index.php(126): require('C:\\laragon\\www\\...') #2 {main} thrown
File: modules\pdf_injector_v2.2.0\batch.php
Line: 123
Pass event_id from hooks to initiators.
I´m trying to download the EM via the REDCap Repo since the last week but when I clic on download, it shows and alert saying "An error occurred because the External Module could not be found."
Not sure if you can fix it or REDCap Staff does.
Thank you anyway!
Can't seem to get the checkbox or radio button to work. Also, tried and followed the instruction to use the True/False field type and still doesn't work. Not sure if this is supported? Many thanks.
Integrate user rights and data access groups
Add z-index.
Really nice work and appreciate the effort on this.
We would love to use this as currently we rely on another EM called 'Custom Template Engine'
It works OK but has problems with the layout at time and depends on the file system preventing the use of load balancing web servers.
The only slight drawback with this EM is the dependency on having to upload to the pdfk
public website - I wonder if it's possible to make an on premise version of this web service somehow?
Cheers,
John
redcap-pdf-injector/pdfInjector.php
Line 333 in a61d50c
Since Version 14.0.0 (released on 2023-11-30) there are multiple redcap_data tables. Use REDCap::getDataTable($pid) to retrieve correct one.
Some of the test cases do not work when REDCap Authentication is enabled.
To be tested and fixed.
It'd be great to be able to specify a form upload field within the project per injection. Then, add a record save hook that would perform the injection, ideally merge/flatten the file, then upload the resulting PDF to the field on the record. This would make the PDF available immediately on a form or even a survey page without clicking through the injection screens.
A particular use-case would be a legal or medical survey where the anonymous end-user would complete details in a traditional REDCap survey, during which it would automatically fill fields on associated "paper" documents that need to be stored with the survey. Both the end-user and REDCap operators would have access to the same file as it was recorded at the time of the survey.
Hi,
I have created a fillable pdf on the server sejda.com, then I used pdftk and the final version of the document I uploaded through the module. After upload there are no fields for filling but they were created in the document.
Thanks in advance.
Add a feature that supports adding injections to forms/surveys.
This could be implemented through a custom Action Tag.
Important would be to validate that all required fields for the injection are available and accessible.
The download could be hooked into the same method that currently fills PDF documents.
Uncaught TypeError: this._config is undefined
probably related to https://stackoverflow.com/questions/74747140/bootstrap-error-this-config-is-undefined
@tertek, specifically the PAGE === "ExternalModules/index.php"
check does not work as expected. I'm scheming the best recommendation to fix this... I wonder if updating the $module->isPage()
method as follows is the most intuitive:
isPage([$path]) | 9.7.6 | Prior to framework version 14,
$path
is required andtrue
is returned if the current page matches a path under the REDCap directory (e.g.Design/online_designer.php
). For framework version 14 and later,$path
is optional. If specified,true
is also returned if$path
matches the name/path for a module page (e.g.some-module-page
). If$path
is not specified,true
is returned if any page for the current module is being displayed.
What do you think? Do have have any alternative ideas?
ArgumentCountError: Too few arguments to function Files::deleteFileByDocId(), 1 passed in \www\redcap\modules\pdf_injector_v2.2.0\pdfInjector.php on line 686 and exactly 2 expected in \www\redcap\redcap_v13.1.7\Classes\Files.php:1229
When clicking "Reset" on Report page, the DOM area where PDFI Button is embedded will be reloaded, without restarting ObjectObserver. No Button will be embedded.
Solution: Bind to "Reset" event an restart ObjectObserver.
On PHP8 PDF Injector will throw the following error when accessing the module page, if:
REDCap crashed due to an unexpected PHP fatal error!
Error message: Uncaught ValueError: Path cannot be empty in modules/pdf_injector_v2.1.0/pdfInjector.php:828 Stack trace: #0 modules/pdf_injector_v2.1.0/pdfInjector.php(828): file_get_contents() #1 modules/pdf_injector_v2.1.0/Injections.php(54): STPH\pdfInjector\pdfInjector->base64FromId() #2 redcap_v12.0.25/ExternalModules/index.php(126): require('...') #3 {main} thrown
File: modules/pdf_injector_v2.1.0/pdfInjector.php
Line: 828
Possible problem:
The documents are not ported during export, having an non-existing $path
. This why the function file_get_contents($path)
call at line 828 throws above error.
Suggestion to fix:
Check if $path
is true:
if($path) {
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
return 'data:image/' . $type . ';base64,' . base64_encode($data);
}
The 'pdf_injector' module threw the following exception when calling the hook method 'redcap_every_page_top':
TypeError: array_diff_assoc(): Argument #1 ($array) must be of type array, string given in /var/www/html/redcap/modules/pdf_injector_v2.2.0/pdfInjector.php:736
Stack trace:
#0 /var/www/html/redcap/modules/pdf_injector_v2.2.0/pdfInjector.php(736): array_diff_assoc()
#1 /var/www/html/redcap/modules/pdf_injector_v2.2.0/pdfInjector.php(547): STPH\pdfInjector\pdfInjector->hasUpdate()
#2 /var/www/html/redcap/modules/pdf_injector_v2.2.0/pdfInjector.php(598): STPH\pdfInjector\pdfInjector->handlePost()
#3 /var/www/html/redcap/modules/pdf_injector_v2.2.0/pdfInjector.php(76): STPH\pdfInjector\pdfInjector->initModule()
#4 /var/www/html/redcap/redcap_v12.4.19/ExternalModules/classes/ExternalModules.php(3229): STPH\pdfInjector\pdfInjector->redcap_every_page_top()
#5 /var/www/html/redcap/redcap_v12.4.19/ExternalModules/classes/ExternalModules.php(3374): ExternalModules\ExternalModules::startHook()
#6 /var/www/html/redcap/redcap_v12.4.19/ExternalModules/classes/ExternalModules.php(3407): ExternalModules\ExternalModules::ExternalModules\{closure}()
#7 /var/www/html/redcap/redcap_v12.4.19/Classes/Hooks.php(42): ExternalModules\ExternalModules::callHook()
#8 /var/www/html/redcap/redcap_v12.4.19/Classes/HtmlPage.php(127): Hooks::call()
#9 /var/www/html/redcap/redcap_v12.4.19/Views/HeaderProject.php(32): HtmlPage->PrintHeader()
#10 /var/www/html/redcap/redcap_v12.4.19/ProjectGeneral/header.php(4): require('...')
#11 /var/www/html/redcap/redcap_v12.4.19/ExternalModules/index.php(118): require_once('...')
#12 {main}
To decrease amount of needed @CALCTEXT annotations for multiple-choice fields this feature could increase UX:
During PDF Injection Render:
radio_button: fetch label for value
checkbox: fetch label for value
default: return value
Find ways to reduce memory needed.
Add try catch block to notify user about memory_limit exception!
DataExport::buildReportDynamicFilterLogic()
DataExport::doReport()
Currently only first checkbox value will be rendered. Add support to output multiple comma-separated values.
When trying single injection:
REDCap crashed due to an unexpected PHP fatal error!
Error message: Uncaught Exception: Statement preparation failed in redcap_v14.0.8\Classes\System.php:2447 Stack trace: #0 redcap_v14.0.8\Config\init_functions.php(301): System::queryWithParameters(Object(mysqli), 'SELECT element_...', Array, 0) #1 redcap_v14.0.8\ExternalModules\classes\ExternalModules.php(2919): db_query('SELECT element_...', Array) #2 redcap_v14.0.8\ExternalModules\classes\framework\Framework.php(2544): ExternalModules\ExternalModules::query('SELECT element_...', Array) #3 [internal function]: ExternalModules\Framework->query('SELECT element_...', Array) #4 redcap_v14.0.8\ExternalModules\classes\framework\Framework.php(341): call_user_func_array(Array, Array) #5 redcap_v14.0.8\ExternalModules\classes\AbstractExternalModule.php(109): ExternalModules\Framework->callFromModuleInstance('query', Array) #6 redcap_v14.0.8\ExternalModules\classes\AbstractExternalModule.php(216): ExternalModules\AbstractExternalModule->call('query', Array) #7 modules\pdf_injector_v2.5.1\pdfInjector.php(226): ExternalModules\AbstractExternalModule->query('SELECT element...', Array) #8 modules\pdf_injector_v2.5.1\pdfInjector.php(294): STPH\pdfInjector\pdfInjector->getValidationTypeData('18', Array) #9 modules\pdf_injector_v2.5.1\preview.php(13): STPH\pdfInjector\pdfInjector->renderInjection('17', '1', '18', 'pdf') #10 redcap_v14.0.8\ExternalModules\index.php(146): require('C:\laragon\www\...') #11 {main} Next Exception: An error occurred while running an External Module query: 'Statement preparation failed'. The error from the database was: 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') AND element_validation_type IS NOT NULL' at line 1'. See the server error log for more details. in redcap_v14.0.8\ExternalModules\classes\ExternalModules.php:2933 Stack trace: #0 redcap_v14.0.8\ExternalModules\classes\framework\Framework.php(2544): ExternalModules\ExternalModules::query('SELECT element...', Array) #1 [internal function]: ExternalModules\Framework->query('SELECT element_...', Array) #2 redcap_v14.0.8\ExternalModules\classes\framework\Framework.php(341): call_user_func_array(Array, Array) #3 redcap_v14.0.8\ExternalModules\classes\AbstractExternalModule.php(109): ExternalModules\Framework->callFromModuleInstance('query', Array) #4 redcap_v14.0.8\ExternalModules\classes\AbstractExternalModule.php(216): ExternalModules\AbstractExternalModule->_call('query', Array) #5 modules\pdf_injector_v2.5.1\pdfInjector.php(226): ExternalModules\AbstractExternalModule->query('SELECT element...', Array) #6 modules\pdf_injector_v2.5.1\pdfInjector.php(294): STPH\pdfInjector\pdfInjector->getValidationTypeData('18', Array) #7 modules\pdf_injector_v2.5.1\preview.php(13): STPH\pdfInjector\pdfInjector->renderInjection('17', '1', '18', 'pdf') #8 redcap_v14.0.8\ExternalModules\index.php(146): require('C:\laragon\www\...') #9 {main} thrown
File: redcap_v14.0.8\ExternalModules\classes\ExternalModules.php
Line: 2933
Error when previewing the newly injected PDF file.
ENVIRONMENTS:
REDCap 11.1.15 · PHP 7.4.20 (Windows OS) · MariaDB 10.3.12
Hi Tertek,
Thank you for this module. They are very helpful. Was wondering if this module accepts longitudinal data? I plan to map the fields to multiple events. Example [event_1][name] on document 1 and [event_2][name] on document 2. Doesn't seem like I'm able to do that. Let me know if you have a way to do that.
Cheers,
Brian
Detect field validation for date fields and render during injection accordingly.
Current state: field validation is handled client-side, so that the injected value is always a default format from the database.
Any chance the changes for this module can be pushed into the REDCap Repo version? We would love to use this module but cannot currently due to the version we are on. Thanks!
TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in /var/www/html/redcap/modules/pdf_injector_v3.0.2/pdfInjector.php:587
Stack trace:
#0 /var/www/html/redcap/modules/pdf_injector_v3.0.2/pdfInjector.php(587): count()
#1 /var/www/html/redcap/modules/pdf_injector_v3.0.2/pdfInjector.php(736): STPH\pdfInjector\pdfInjector->setTaggedFields()
#2 /var/www/html/redcap/modules/pdf_injector_v3.0.2/pdfInjector.php(91): STPH\pdfInjector\pdfInjector->initPageDataEntry()
#3 /var/www/html/redcap/redcap_v14.0.16/ExternalModules/classes/ExternalModules.php(3179): STPH\pdfInjector\pdfInjector->redcap_data_entry_form()
#4 /var/www/html/redcap/redcap_v14.0.16/ExternalModules/classes/ExternalModules.php(3346): ExternalModules\ExternalModules::startHook()
#5 /var/www/html/redcap/redcap_v14.0.16/ExternalModules/classes/ExternalModules.php(3379): ExternalModules\ExternalModules::ExternalModules{closure}()
#6 /var/www/html/redcap/redcap_v14.0.16/Classes/Hooks.php(41): ExternalModules\ExternalModules::callHook()
#7 /var/www/html/redcap/redcap_v14.0.16/DataEntry/index.php(1928): Hooks::call()
#8 {main}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.