Generate MS word document in Joomla - joomla

What I try to accomplish:
Admin creates MS Word document with placeholders that will be filled with data from Joomla database
Admin uploades MS Word file to Joomla and connects it with SQL statement
User execute "Generate MS Word" function and gets MS Word document filled with data from database.
Is there any components for Joomla that does this?
I have done this in my application using Interop libraries.

recently I've done this for a joomla component using phpdocx and pclzip libraries, where
a *.docx file is generated from a template file.
Config:
$params = Object with form data; // data from requeest
$template = 'xml_file_name'; // jfrom xml file name and *.docx template file name
$pl = '#'; // place holder prefix & suffix: (example: #PLACEHOLDER#)
$date_placehold = '#DATE#'; // will be replaced with current date
$date_formt = 'F j, Y'; // php date format
$template_path = JPATH_COMPONENT_SITE .DS.'templates'.DS.$template.'.docx';
$temp_dir = JPATH_ROOT.DS.'tmp'.DS.'phpdocx-temp-dir'; // + write access
$output_mime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
$filename = $params->first_name .' - '. $params->second_name.'.docx';
// get names of all form fields of type 'list' from xml file
$lists = (array) ComponentHelper::getJFormLists($template);
// get all field names from the xml file
$fields = (array) ComponentHelper::getJFormFieldsNames($template);
Initialize variables:
$doc =& JFactory::getDocument();
$doc->setMimeEncoding($output_mime);
// require phpdocx class
require_once(JPATH_COMPONENT_ADMINISTRATOR . DS . 'helpers'.DS.'pclzip.lib.php');
require_once(JPATH_COMPONENT_ADMINISTRATOR . DS . 'helpers'.DS.'phpdocx.php');
$phpdocx = new phpdocx($template_path, $temp_dir);
bind form fields with user params:
foreach($params as $field => $value)
{
if(array_key_exists($field,$lists) && is_array($lists[$field]) && array_key_exists($value, $lists[$field]) )
{
// if the field is JFormInput with type "list" its value is not important but its label
$var = $lists[$field][$value];
} else {
$var = $value;
}
// use openxml carriage return on new lines
if(strpos($var, "\n")) {
$var = str_replace("\n", '<w:br/>', $var);
}
$fields[$field] = $var;
}
foreach application form fields:
foreach($fields as $field => $value)
{
// replace placeholder with form value
$phpdocx->assign($pl.strtoupper($field).$pl, $value);
}
// assign date for filled-in applications
if(!empty($date_placehold)
{
$phpdocx->assign($date_placehold, date($date_formt));
}
output the file:
$phpdocx->stream($filename, $output_mime);
return true;

Related

laravel Backpack Original Image Name

I am using laravel backpack for my site and i need to upload some images, i copy the code from their website and works fine, but i need the original name on the images, i tried some things, but is not working.
public function setImageAttribute($value)
{
$attribute_name = "image";
$disk = "uploads";
$destination_path = 'storage/services/' .date('FY').DIRECTORY_SEPARATOR;
if ($value==null) {
Storage::disk($disk)->delete($this->{$attribute_name});
// set null in the database column
$this->attributes[$attribute_name] = null;
}
if (str_starts_with($value, 'data:image'))
{
$file = $value;
$filename = $this->generateFileName($file, $destination_path);
$image = InterventionImage::make($file)->orientate();
$fullPath = $destination_path.$filename.'.'.$file->getClientOriginalExtension();
$this->attributes[$attribute_name] = $fullPath;
}
protected function generateFileName($file, $destination_path)
{
$filename = basename($file->getClientOriginalName(), '.'.$file->getClientOriginalExtension());
$filename = Str::random(20);
while (Storage::disk('uploads')->exists($destination_path.$filename.'.'.$file->getClientOriginalExtension())) {
$filename = Str::random(20);
}
return $filename;
}
why value alwys take image base64
is there any way to git image original name?
As far as I know, you won't be able to retrieve the filename, as it's always a base64 file. But maybe this work around helps you:
Image fields blade file can be found at:
\vendor\backpack\crud\src\resources\views\crud\fields\image.blade.php
You can overwrite it by making a file on the same name at:
\resources\views\vendor\backpack\crud\fields\image.blade.php
You can change anything there, maybe you can add a hidden input with the file name.

How can I export data tab separated

I'm exporting some Data from a DB and I want to have the 2 columns that I generate Tab separated.
I've already tried to use implode after my fputcsv but it always appears comma separated. Also tried changing my separator (,) to some other character, but a comma is always printed in the CSV.
This is the function that I'm using for it.
public function ResearchExport(Request $request)
{
//Export ProductID and KitID of all the Kits created from the given date to the actual moment
$TubeAddDate = $request->input('TubeAddDate');
$select = DB::table('tubes')->select('TubeBarcodeID', 'ActivationCode')->where('LOG_important', '2')->whereBetween('TubeAddDate', array($TubeAddDate, NOW()))->get();
$tot_record_found=0;
if (count($select)>0) {
$tot_record_found=1;
$CsvData=array('TubeBarcodeID,ActivationCode');
foreach ($select as $value) {
$CsvData[]=$value->TubeBarcodeID.",".$value->ActivationCode.;
}
$filename=date('Y-m-d').".csv"; //stores the file with the date of today as name
$file_path=storage_path().'/'.$filename;
$file = fopen($file_path, "w+");
foreach ($CsvData as $exp_data) {
fputcsv($file, explode(",", $exp_data));
}
fclose($file);
return response()->download($file_path, $filename);
}
return view('InsertForms/download', ['record_found' =>$tot_record_found]);
}
At the moment I'm getting this as output
TubeBarcodeID,ActivationCode
FF01111112,IKG5G-B0FIZ
FF0111113,6XMP8-760Y3
but I expect something tab separated in the CSV like this
TubeBarcodeID ActivationCode
FF01111112 IKG5G-B0FIZ
FF0111113 6XMP8-760Y3
So I actually just solved thanks to one of the commentaries that pointed out my error.
I just had to change my .csv to .xls and then override the third parameter of fputcsv with a "\t".
$filename=date('Y-m-d').".xls"; //stores the file with the date of today as name
$file_path=storage_path().'/'.$filename;
$file = fopen($file_path, "w+");
foreach ($CsvData as $exp_data) {
fputcsv($file, explode(",", $exp_data), "\t");
}

magento 2 read csv from ftp returns a string and not an array

I'm working with Magento 2, I need to read a file through ftp connection. I can login to ftp but I cannot read the csv file. What I did so far (I cut all the unnecessary parts):
use Magento\Framework\File\Csv;
use Magento\Framework\Filesystem\Io\Ftp;
class MyClass {
protected $_csvprocessor;
protected $_ftp;
public function __construct(Csv $csvprocessor, Ftp $ftp) {
$this->_csvprocessor = $csvprocessor;
$this->_ftp = $ftp;
}
public function getCsv() {
$conn = $this->_ftp->open($params); // this works, I can successfully login to ftp
$filecsv = $this->_ftp->read($remotepathtofile); // this gets me the file but it is a string, not an array with the csv data
$this->_csvprocessor->getData($remotepathtofile); // this doesn't work with remote file, only with local path (eg: magentoroot/var/import/file.csv)
}
}
How can I read the csv as an array, as $this->_csvprocessor->getData() would return, but from remote file instead of local?
You need to parse the csv string. Try using the function "fgetcsv". See http://php.net/manual/en/function.fgetcsv.php.
Below the code, you can use to read CSV file an array
use Magento\Framework\App\Bootstrap;
include('app/bootstrap.php');
$bootstrap = Bootstrap::create(BP, $_SERVER);
$objectManager = $bootstrap->getObjectManager();
$objectManager1 = Magento\Framework\App\ObjectManager::getInstance();
$directoryList = $objectManager1->get('\Magento\Framework\App\Filesystem\DirectoryList');
$path = $directoryList->getPath('media');
$state = $objectManager->get('Magento\Framework\App\State');
$state->setAreaCode('frontend');
$myarray = glob("Book1.csv");
usort($myarray, create_function('$a,$b', 'return filemtime($a) - filemtime($b);'));
if(count($myarray)){
/*This will create an array of associative arrays with the first row column headers as the keys.*/
$csv_map = array_map('str_getcsv', file($myarray[count($myarray)-1]));
array_walk($csv_map, function(&$a) use ($csv_map) {
$a = array_combine($csv_map[0], $a);
});
array_shift($csv_map); # remove column header
/*End*/
$message = '';
$count = 1;
foreach($csv_map as $data){
your code....
}
Hope this will help you enjoy...
You can dump the server file to your local.
$filecsv = $this->_ftp->read($remotepathtofile, $destinationFilePath);
where $destinationFilePath is local file path.
Then use that local file.

How to return variable values in codeigniter language line strings?

To be more clear, none of these lines in default language's general_lang.php work:
$lang['general_welcome_message'] = 'Welcome, %s ( %s )';
or
$lang['general_welcome_message'] = 'Welcome, %1 ( %2 )';
I expect an output like Welcome, FirstName ( user_name ).
I followed the second (not accepted) answer at https://stackoverflow.com/a/10973668/315550.
The code I write in the view is:
<div id="welcome-box">
<?php echo lang('general_welcome_message',
$this->session->userdata('user_firstname'),
$this->session->userdata('username')
);
?>
</div>
I use codeigniter 2.
You will need to use php's sprintf function (http://php.net/manual/en/function.sprintf.php)
Example from http://ellislab.com/forums/viewthread/145634/#749634:
//in english
$lang['unread_messages'] = "You have %1$s unread messages, %2$s";
//in another language
$lang['unread_messages'] = "Hi %2$s, You have %1$s unread messages";
$message = sprintf($this->lang->line(‘unread_messages’), $number, $name);
I extended Code CI_Lang class like this..
class MY_Lang extends CI_Lang {
function line($line = '', $swap = null) {
$loaded_line = parent::line($line);
// If swap if not given, just return the line from the language file (default codeigniter functionality.)
if(!$swap) return $loaded_line;
// If an array is given
if (is_array($swap)) {
// Explode on '%s'
$exploded_line = explode('%s', $loaded_line);
// Loop through each exploded line
foreach ($exploded_line as $key => $value) {
// Check if the $swap is set
if(isset($swap[$key])) {
// Append the swap variables
$exploded_line[$key] .= $swap[$key];
}
}
// Return the implode of $exploded_line with appended swap variables
return implode('', $exploded_line);
}
// A string is given, just do a simple str_replace on the loaded line
else {
return str_replace('%s', $swap, $loaded_line);
}
}
}
ie. In your language file:
$lang['foo'] = 'Thanks, %s. Your %s has been changed.'
And where-ever you want to use it (controller / view etc.)
echo $this->lang->line('foo', array('Charlie', 'password'));
Will produce
Thanks, Charlie. Your password has been changed.
This handles single 'swaps' as well as multiple
Also it won't break any existing calls to $this->lang->line.

How to set Component parameters in J2.5?

I've created a J2.5 component with some config fields using config.xml in the admin folder of the component.
How can I set parameters in the config programatically?
I've tried the code bellow, but it obviously doesn't save the result to the DB:
$params = & JComponentHelper::getParams('com_mycomponent');
$params->set('myvar', $the_value);
Could anyone please show some examples of how to achieve this?
The safest way to do this would be to include com_config/models/component.php and use it to validate and save the params. However, if you can somehow validate the data params yourself I would stick with the following (much more simple solution):
// Get the params and set the new values
$params = JComponentHelper::getParams('com_mycomponent');
$params->set('myvar', $the_value);
// Get a new database query instance
$db = JFactory::getDBO();
$query = $db->getQuery(true);
// Build the query
$query->update('#__extensions AS a');
$query->set('a.params = ' . $db->quote((string)$params));
$query->where('a.element = "com_mycomponent"');
// Execute the query
$db->setQuery($query);
$db->query();
Notice how I cast the params to a string (when building the query), it will convert the JRegistry object to a JSON formatted string.
If you get any caching problems, you might want to run the following after editing the params:
From a model:
$this->cleanCache('_system');
Or, else where:
$conf = JFactory::getConfig();
$options = array(
'defaultgroup' => '_system',
'cachebase' => $conf->get('cache_path', JPATH_SITE . '/cache')
);
$cache = JCache::getInstance('callback', $options);
$cache->clean();
The solution is here...
http://www.webtechriser.com/tutorials/82-joomla-3-0/86-how-to-save-component-parameters-to-database-programmatically
You can replace in Joomla 2.5+ the
// check for error
if (!$table->check()) {
$this->setError('lastcreatedate: check: ' . $table->getError());
return false;
}
if (!$table->store()) {
$this->setError('lastcreatedate: store: ' . $table->getError());
return false;
}
with
if (!$table->save()) {
$this->setError('Save Error: ' . $table->getError());
return false;
}

Resources