pdftk error when using checkbox on pdf form - pdftk

When I use checkbox on pdf form, pdftk gives the following error and does not create output pdf.
Unhandled Java Exception:
Unhandled Java Exception:
java.lang.NullPointerException
at gnu.gcj.runtime.NameFinder.lookup(libgcj.so.12)
at java.lang.Throwable.getStackTrace(libgcj.so.12)
at java.lang.Throwable.stackTraceString(libgcj.so.12)
at java.lang.Throwable.printStackTrace(libgcj.so.12)
at java.lang.Throwable.printStackTrace(libgcj.so.12)

Today I am having a similar problem with Checkbox. And I also saw java.lang.NullPointerException error. After investigation, I found that it is because my fillable checkbox is using custom glyphicon ('X') as checkmark instead of default styling.
So after reading this answer https://stackoverflow.com/a/29034948/11898471, It does workout by getting rid of my custom checkbox glyphicon. Without seeing your code I don't know exactly how you may do it your way, but my situation is to flatten a client uploaded PDF form with custom checkbox. What I did, is to extract all form data and re-fill the form so they get rid of all custom checkbox markup. Something like:
$pdf = new Pdf($uploadedFile->getRealPath(), ['command' => env('PDFTK_PATH')]);
/* Extract form field to remove custom markup field that cannot be filled. Eg: custom checkbox icon */
$pdf2 = new Pdf($uploadedFile->getRealPath(), ['command' => env('PDFTK_PATH')]);
$data = $pdf2->getDataFields();
$data = (array) $data;
$fill_data = [];
foreach ($data as $field) {
if (isset($field['FieldValue'])) {
$fill_data[$field['FieldName']] = $field['FieldValue'];
}
}
/* Update form field */
$pdf->fillForm($fill_data)
->flatten()
->saveAs(storage_path('app/'.$flattenedFilename));

Related

MailChimp Campaign Content Update

MailChimp campaign content docs - https://developer.mailchimp.com/documentation/mailchimp/reference/campaigns/content
I'm trying to replace some placeholders in a campaign content with actual values via the API. At first, I thought there might be some syntax errors or internal logic errors like non-unique mc:edits into a mc:repeatable that would get the HTML refused/declined by MailChimp, hence the update not taking place, however, that was not the case.
Tried replacing html with a simple <p>test</p> and it was still not working.
Here are a couple of local logs, I'll use xyz as my campaign id:
2018-02-26 16:26:13 [::1][9804][-][warning][application] calling GET /campaigns/xyz/content []
2018-02-26 16:26:13 [::1][9804][-][warning][application] got both plain_text and html versions of content
2018-02-26 16:26:13 [::1][9804][-][warning][application] calling PUT /campaigns/xyz/content {"html":"<p>test</p>"}
2018-02-26 16:26:14 [::1][9804][-][warning][application] got response [
'plain_text' => 'test' + other MailChimp stuff such as footer, that were appended automatically by MailChimp,
'html' => '<p>test</p>'
]
// calling GET immediately after PUT in order to see if any update occurred
2018-02-26 16:26:14 [::1][9804][-][warning][application] calling GET /campaigns/xyz/content []
2018-02-26 16:26:14 [::1][9804][-][warning][application] got updated html (my "test" paragraph + auto footer from MailChimp) and proper plain_text
Everything looks fine according to these, that means both versions updated as they were supposed to. However, on the next API/MailChimp dashboard request, it displays the old HTML content, preserving the update I've just made in the plain text version only.
No errors, nothing to look into. It could be any internal MailChimp behaviour.
PS: I know about Setting Mailchimp campaign content html not working or MailChimp API v3 campaign content template sections, but none of the answers provided to those are helpful.
PS2: I know I should contact MailChimp, but according to
Our MailChimp Support Team isn't trained at in-depth API troubleshooting. If you need a developer to help you configure something using the API, check out our great Experts Directory, which lists third-party MailChimp experts who can be hired to help out.
they don't provide support for API troubleshooting.
MailChimp doesn't allow updating the campaign's HTML content because the campaign type is based on a template.
In order to update the HTML content, the campaign has to be set to custom HTML instead of a template. You can check the type by sending a GET API request to /campaigns or /campaigns/{campaign_id} and finding the content_type attribute in the response (documentation).
Alternatively, in the dashboard, the type can be determined by editing the design of the email. Anything under 'Code your own' is HTML and templates are of course templates.
I'm not entirely sure why the first response to a PUT request on a template campaign shows the updated content, but changing the content type should let you update as you want to.
Hope this helps!
If anyone's still looking for an answer to this.
I managed to solve the issue several weeks ago without creating the campaign via API, but actually updating it.
I used placeholders like [product_card id=123], 3 cards per block/row, all repeatable, which are wrapped in a class that I named product-card. In the MailChimp dashboard, you may still see the placeholders, but on preview and any form of preview like thumbnail, it will display correctly.
On the server, I crawl through the campaign's content, "detect" section names based on how they seemed to me in MailChimp and update each section with the content that I want.
PHP snippet below, some Yii2 stuff, but mostly plain PHP. I use $preview to display a preview of how the template would look, I know it's not visible in the function.
/**
* #param $id - Id of the campaign
* #param $s - Whether to save or just preview
*
* #return bool
*/
function changeContent($id, $s = false)
{
$mcCampaign = new McCampaign();
$mcCampaign::$itemId = $id;
$content = $this->api->get("/campaigns/{$id}/content");
if (!isset($content['html'])) return false;
$template = $content['html'];
$forgedDom = new \DOMDocument();
$forgedDom->loadHTML($template);
$mcSections = [];
$finder = new \DOMXPath($forgedDom);
$nodes = $finder->query('//td[contains(#class, "product-card")]');
// disabling this shit in order to avoid strict errors
libxml_use_internal_errors(true);
$mcEditId = 1;
$mcEditIndex = 0;
foreach ($nodes as $key => $node) {
/** #var \DOMElement $node */
$textContent = $node->textContent;
if (!preg_match("#\[product_card id=\d+\]#", $textContent)) continue;
$productId = filter_var($textContent, FILTER_SANITIZE_NUMBER_INT);
$node->textContent = false;
$product = Product::findOne($productId);
$productDetails = $product ? $this->renderPartial('/partials/_mc-product', [
'product' => $product
]) : 'Product not found.';
if ($key != 0) {
if ($key % 3 == 0) {
$mcEditId = 1;
$mcEditIndex++;
} else {
$mcEditId++;
}
}
$mcSections["repeat_1:{$mcEditIndex}:product_card_{$mcEditId}"] = $productDetails;
$fragment = $forgedDom->createDocumentFragment();
$fragment->appendXML($productDetails);
$node->appendChild($fragment);
}
libxml_use_internal_errors(false);
$preview = $forgedDom->saveHTML();
// just in case
/* $preview = str_replace(["\n", "\t", "\r"], "", $preview); */
if ($s) {
if (!empty($mcSections)) {
$res = $this->api->put("/campaigns/{$id}/content", [
'template' => [
'id' => *template_id_here*,
'sections' => $mcSections
],
]);
// forcing Mc to rebuild cache
$this->api->get("/campaigns/{$id}/content");
Yii::$app->session->setFlash('success', 'Done.');
return $this->redirect(['campaign/index']);
} else {
Yii::$app->session->setFlash('error', 'Something went wrong.');
}
}
}

Dynamic form Issue in Angular

Scenario :
A form is generated dynamically, I used this tutorial to create the form dynamically. When I click "Submit" button, the form value I get in the component is
ts :
doSubmitICR(form) {
console.log(form.value);
}
form.value has the following values
{
CaptainPoint:"0",
Category:"restaurant",
Description:"Test",
DisplayDept:"kitchen",
Group:"restaurant",
GuestPoint:"0",
ItemCode:"1",
ItemName:"Test Item",
PrintingDept:"frontoffice",
SalesRate:"3",
SubGroup:"restaurant",
TAX1:true,
TAX2:true,
TabDisplay:"restaurant",
Unit:"restaurant"
}
TAX1 and TAX2 are dynamic, those form controls were created from a tax table, If the table has TAX3 and TAX4, then instead of TAX1 and TAX2 in the above form, TAX3 and TAX4 form control is generated.
Issue :
If the TAXs are dynamic, how can I pass these values to Web service say WebAPI2 as a model?
Is it possible to filter only the TAX element from the form.value?
Any advice would be appreciated. Thank you.
The solution from alexKhymenko should work well. Alternatively, if the values you want to submit to the API will always have the format of TAX{d}, where d is some combination of digits, you could use the following to get just those values on a request object:
let request = {};
Object.keys(form.value).forEach(key => {
if(/^TAX[\d]+$/.test(key))
request[key] = form.value[key]
});

PhpUnit form does not submit, no error

I'm doing a functional test in PhpUnit to test simple modal window functionality which has only one field and two buttons (i have tried various ways so the code may be not clean, I'm pasting just to show the idea):
$form = $crawler
// find all buttons with the text "Pridėti"
->filter('button:contains("Pridėti")')
->eq(0)
->form()// select the first button in the list
;
$form['appbundle_classinfo[name]'] = '5a';
$crawler = $client->submit($form);
//It doesn't even save to database
$container = self::$kernel->getContainer();
$em = $container->get('doctrine')->getManager();
$classinfo = $em->getRepository('AppBundle:ClassInfo');
//Echoes modal window
echo $client->getResponse()->getContent() ;die;
I also tried to var_dump the form, it shows that the value is added to form:
string(25) "appbundle_classinfo[name]"
["value":protected]=>
string(2) "5a"
So the form is not submitted. Can you help me find out why?
<?php
namespace AppBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PostTest extends WebTestCase
{
public function testShowPost()
{
//returns a Client, your browser use your web site
$client = static::createClient();
// The request() method (read more about the request method) returns a Crawler object which can be used to select elements in the response, click on links and submit forms.
$crawler = $client->request('GET', '/your/route/controller/action');
// select button by name or id
$form = $crawler->selectButton('Login')->submit();
//submit the form
$crawler->submit($form);
$this->assertGreaterThan(
0,
$crawler->filter('html:contains("hello world")')->count()
);
// get HTML content returned
dump($client->getResponse()->getContent());
}
http://symfony.com/doc/current/testing.html#functional-tests
hope that were useful, let me know.

Contactform 7 Placeholder Validation

I'm using Contactform 7 for Wordpress. I've edited the text.php and textarea.php to enable the use of placeholders. That works fine.
But, the validation isn't working for some input fields, 'cause the validation thinks the placeholder is the actual text being validated. And yes, ofcourse that validates true 'cause it's not empty.
My input fields with placeholders are as follows:
Your name
Your e-mailadress
Your telephone number
and so on.
In contactform 7's scripts.js I want the validation to check if the input isn't the same as the placeholder. So if the input value is the same as the placeholder value, do the CF7's error validation.
Any idea?
In scripts.js of the contactform 7 plugin folder
Change this:
var submit = form.find('input:submit');
if (! submit.length) return;
with this:
var submit = form.find('input:submit');
if (! submit.length || submit == this.find('[placeholder]').wpcf7Placeholder()) return;

Zend Framework export Doctrine query results to XML file

I have a need to export certain queries to xml files. I have this working in that the file is created and the data are exported, however I'm receiving the following error on screen as the file is being exported and not displayed.
This page contains the following errors:
error on line 3 at column 1: Extra content at the end of the document
I'll admit that I'm new to this as most of you are aware but is there a way I can export and just display a confirmation message to the user that the report has been saved, or am I going about this the wrong way completely?
My code is below
My controller
public function init()
{
// allow certain reports to be exported to xml
// initialize context switch helper
$contextSwitch = $this->_helper->getHelper('contextSwitch');
$contextSwitch->addActionContext('newsletterexport', 'xml')
->initContext();
}
public function newsletterexportAction()
{
$q = Doctrine_Query::create()
->select('c.firstname,c.lastname,c.address1,c.address2,c.address3,t.county')
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties t')
->where('c.consentToNews=1');
$result = $q->fetchArray();
if (count($result) >= 1) {
$this -> view -> records = $result;
}
}
EDIT
Ok I tried moving the code from the xml.phtml into my controller as suggested and tried to save the document with save, but now I get the start of the xml document as shown below but no records are saved to the document.
<?xml version="1.0" encoding="utf-8"?>
<petmanager:document xmlns:petmanager="http://petmanager"><petmanager:records/></petmanager:document>
My controller code as of this edit
public function newsletterexportAction()
{
$q = Doctrine_Query::create()
->select('c.firstname,c.lastname,c.address1,c.address2,c.address3,t.county')
->from('PetManager_Model_Clients c')
->leftJoin('c.PetManager_Model_Counties t')
->where('c.consentToNews=1');
$result = $q->fetchArray();
if (count($result) >= 1) {
//$this -> view -> records = $result;
$docpref="newsletterexport";
$docDate=date('y-m-d');
$ext=".xml";
$docname=$docpref.$docDate.$ext;
// create XML document
$dom = new DOMDocument('1.0', 'utf-8');
// create root element
$root = $dom->createElementNS('http://petmanager','petmanager:document');
$dom->appendChild($root);
// convert to SimpleXML
$xml = simplexml_import_dom($dom);
// add resultset elements
$records = $xml->addChild('records');
foreach($this->$result as $r){
$record = $records->addChild('record');
$record->addChild('firstName',$this->escape($r['firstName']));
$record->addChild('lastName',$this->escape($r['lastName']));
$record->addChild('address1',$this->escape($r['address1']));
$record->addChild('address2',$this->escape($r['address2']));
$record->addChild('address3',$this->escape($r['address3']));
$record->addChild('county',$this->escape($r['PetManager_Model_Counties']['county']));
}//end of foreach
// saave document
$xml->saveXML();
$dom->save('D:/reports/exports/'.$docname.'');
}
DomDocument::saveXML() doesnt take a file path - it returns the XML document as text. If you want to save it directly as a file like youre doing you use DomDocument::save().
All that logic in your phtml should be in your controller. You have also set the context to xml, so the view is going to output XML to the browser, not HTML... so id doesnt make sense to display a confirmation message unless its encoded in XML, otherwise you need to use the default context (HTML). So if you want to save the file to the webserver and display a confirmation you would do:
public function exportXmlAction(){
// remove the context switch from init
// do your doctrine stuff
// build the xml DOM as $xml
$xml->save('path/to/file');
$this->message = 'File was exported successfully!';
}
// in your phtml
<?php echo $this->message; ?>
If you want to display the xml on screen:
public function exportXmlAction(){
// do your doctrine stuff
// build the xml DOM as $xml
$this->xmlDom = $xml;
}
// in your phtml
<?php echo $this->xmlDom->saveXml(); ?>
The question i have though is whay would a user want ot export xml to the server. When you call DomDocument::save() youre saving that file to a path on the server, not the user's machine so what would be the point of exporting the xml to the server where the user has no access to it?