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?
Related
I try to add new value to array in php file with Zend\Config\Factory:
public function testFunc($testParam)
{
$testArray = $this->testFunc1($testParam);
if(!is_null($testArray[1])) {
foreach ($testArray[1] as $array) {
$this->testFunc($array);
}
}
$filename = getcwd() . '/data/config/config.php';
$configFile = \Zend\Config\Factory::fromFile($filename);
$configFile[] = $testArray[0];
if(!\Zend\Config\Factory::toFile($filename, $configFile)) {
throw new Exception\RuntimeException("Can't put content to $filename.");
}
return true;
}
The problem is such that in $filename file saves only value from first function call and not from recursion.
[UPDATE]
I debug \Zend\Config\Factory::fromFile and found if I wanna to load php file, function load file that:
........
$config = include $filepath;
in recursion \Zend\Config\Factory::toFile update my php file(i checked config.php file) and then in first function call \Zend\Config\Factory::fromFile get again php file without changes and overwrite config.php. As a consequence , is recorded only value from first function call in config.php.
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));
I have:
$this->_helper->layout->disableLayout();
$this->_helper->viewRenderer->setNoRender();
$this->render("voucher-list");
The problem is, when I execute:
$this->render("voucher-list");
It actually prints the information to screen. I want to return the data as an HTML string. This DOES NOT work:
$htmlcontent = $this->render("voucher-list");
How would I go about returning this information as a string?
If you want to send the data into JSON format then you need to make the array of data and use the following code to send the data:
$data = array(3,4,'test', 'my-name' => 3,4); //suppose this is your data
$this->_helper->viewRenderer->setNoRender(true);
$this->view->layout()->disableLayout();
echo Zend_Json::encode($data);
And you will get the data in JSON format.
See this: Zend Framework JSON Output
I have created the following action, which successfully returns a CSV. however it still returns the layout within the response. From what i have read the layout is not supposed to be returned. aAnyone know how to disable this?
public function csvAction() {
$content = 'test';
$response = $this->getResponse();
$response->getHeaders()
->addHeaderLine('Content-Type', 'text/csv')
->addHeaderLine('Content-Disposition', "attachment; filename=\"my_filen.csv\"")
->addHeaderLine('Accept-Ranges', 'bytes')
->addHeaderLine('Content-Length', strlen($content));
$response->setContent($content);
return $response;
}
Try adding these at the beginning of your csvAction function:
$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender();
I made module addition and in this made three fields amount1_c, amount2_c and total_amount_c to add the two numbers and display the result in the third field. I done coding in the logic looks here is my code
<?
$hook_version = 1;
$hook_array = Array();
$hook_array['before_save'] = Array();
$hook_array['before_save'][] = Array(1,'calculate_field', 'custom/modules/cases/LogicHookMath.php','LogicHookMath', 'calculate_field');
?>
and made one more file logic hook math. here is my code for
<?php
class LogicHookMath {
function calculate_field(&$bean, $event, $arguments) {
$field1 = $bean->amount1_c;
$field2 = $bean->amount2_c;
$field3 = $field1 + $field2;
$bean->amount_total_c = $field3;
}
}
?>
but still i did not get any result. Please help me out for this.
The code looks correct.
Some common "mistakes" when custom logic hooks are not working:
Make sure, the custom logic hook has the correct name (LogicHookMath.php)
Make sure, that the $bean variable is prefixed with &, so the variable is passed as a reference
Make sure the logic_hooks.php and the LogicHookMath.php files are readable by the web server user
The entire custom directory should also be writeable for the web server user
If the above does not help, try logging the progress to the sugarcrm.log using $GLOBALS['log']->info( "Value 3: ". $field3); in the custom logic hook.