Display results based on URL path - php

I'm trying to create a script that displays results based on URL path.
For example, I can have a URL like example.com/A/B/C/D/, example.com/A/B/C/ all the way to example.com/.
A = Year
B = Month
C = Day
D = Title
The script below does a good job of breaking it down.
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$array = explode('/', $path);
The table in the database has a column called 'path'. The path contains '/A/B/C/D/'. Is there an easier way than using multiple if/else statements to accomplish this:
Empty path (home page, limit 5 results:
SELECT * FROM table ORDER BY post_date DESC LIMIT 5;
Search by year:
SELECT * FROM table WHERE path LIKE '/' . $array[1] . '/%';
Search by year and month
SELECT * FROM table WHERE path LIKE '/' . $array[1] . '/' . $array[2] . '/%';
Search by year and month and day
SELECT * FROM table WHERE path LIKE '/' . $array[1] . '/' . $array[2] . '/' . $array[3] . '/%;
Search by year and month and day and title
SELECT * FROM table WHERE path LIKE '/' . $array[1] . '/' . $array[2] . '/' . $array[3] . '/' . $array[4] . '/';
Obviously if the person tries to enter the values (letters) in a different order the results should not be found and an error page be displayed.

Use the array element count to generate your path.
if (count($array)) {
$sql = "SELECT * FROM table WHERE path LIKE '/" . implode($array, '/') . "/%'";
}
Please see SQL Injection

The more cleaner approach would be to define different REST calls for each of the path params. I would use a php micro framework like Flight to handle it. For example if some of the param is not specified then it would be routed to the next and so on. Thus it would be able to handle different params along with the param specific database call. By doing this would eliminate if else logic or any kind of ambiguity.
Look here for reference:
http://flightphp.com/learn#routing
Check the passing mechanism.

Related

Scheduling multiple emails PHP

I've made a system that receives a query, executes it at the database and then creates an HTML table with the data returned. These tables are then saved in the system for further access, and the user can send it via email to multiple receivers.
All works well, but now I have to schedule the emails. Need to send "table X" at a week from now and "table Y" at two weeks. How can I do that? I've looked up for CRONS/WindowsTasks but I don't know how I would make it automatic for every table, since the user can keep creating different tables.
I've used CodeIgniter and PHPMailerMaster to make it happen.
Here is a screenshot of the TableViewer, it's in portuguese, but it contains:
|TITLE | CONFIG | SEND | XLS GENERATOR | LAST SENT |
For each table created. (Just so you can understand how it works)
If anyone got any ideas.
Here is a function that simulates crontab in PHP. You can use this for dynamic crontabs, so each table can have it's own unique frequency.
function parse_crontab($time, $crontab) {
// Get current minute, hour, day, month, weekday
$time = explode(' ', date('i G j n w', strtotime($time)));
// Split crontab by space
$crontab = explode(' ', $crontab);
// Foreach part of crontab
foreach ($crontab as $k => &$v) {
// Remove leading zeros to prevent octal comparison, but not if number is already 1 digit
$time[$k] = preg_replace('/^0+(?=\d)/', '', $time[$k]);
// 5,10,15 each treated as seperate parts
$v = explode(',', $v);
// Foreach part we now have
foreach ($v as &$v1) {
// Do preg_replace with regular expression to create evaluations from crontab
$v1 = preg_replace(
// Regex
array(
// *
'/^\*$/',
// 5
'/^\d+$/',
// 5-10
'/^(\d+)\-(\d+)$/',
// */5
'/^\*\/(\d+)$/'
),
// Evaluations
// trim leading 0 to prevent octal comparison
array(
// * is always true
'true',
// Check if it is currently that time,
$time[$k] . '===\0',
// Find if more than or equal lowest and lower or equal than highest
'(\1<=' . $time[$k] . ' and ' . $time[$k] . '<=\2)',
// Use modulus to find if true
$time[$k] . '%\1===0'
),
// Subject we are working with
$v1
);
}
// Join 5,10,15 with `or` conditional
$v = '(' . implode(' or ', $v) . ')';
}
// Require each part is true with `and` conditional
$crontab = implode(' and ', $crontab);
// Evaluate total condition to find if true
return eval('return ' . $crontab . ';');
}
It's used like this. First parameter is the current time, or time you want to check, second parameter is the crontab.
$time_to_run = parse_crontab(date('Y-m-d H:i:s'), '* * * * *')

Auto cut on thermal printer (php)

How can i perform auto cut on Epson TMT82 from PHP File? bellow is my config file.
Config:
$tmpdir = sys_get_temp_dir();
$file = tempnam($tmpdir, 'ctk');
$handle = fopen($file, 'w');
$condensed = Chr(27) . Chr(33) . Chr(4);
$bold1 = Chr(27) . Chr(69);
$bold0 = Chr(27) . Chr(70);
$initialized = chr(27) . chr(64);
$condensed1 = chr(15);
$condensed0 = chr(18);
$Data = $initialized;
$Data .= $condensed1;
Printing:
fwrite($handle, $Data);
fclose($handle);
copy($file, "//localhost/printer"); # printing
unlink($file)
Try to write chr(29) + 'V' (or chr(86)), and then the values for m and n, depending on the exact function you want to use as per the manual below (if you just want to cut without feeding at all, you want to use function A, which means you can just follow with a 0 (or 48, not sure why they mentioned both numbers in the manual...!?), like so:
chr(29) . "V" . 0
https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=87
(you need to be logged on to read this reference, but registering is free)
Edited: the chr() code for 'V' is 86, not 56
Edit2: Just to comment on what Matt Gibson said; chr(27) . chr(105) should also work on your model (just checked, also chr(27) . chr(109)), but it's an obsolete command, you should be using chr(29) . "V". In any case, some printers like to receive these sorts of commands on their own instead of having them along with the rest of the string.
Once you get this right, you should probably define a variable with the type of cut that you want. Ex. $cutPaper = chr(29) . "V" . 0;

Find a random time with an integer

I am looking to generate a random number say 01:20 and then add 8 hours onto that and store that as a variable. However I want to do this within only the time and not use any random integers.
The date given for the query is found using a preset date at the moment set to 01-01-2017. StaffID is gotten from a loop through another table.
This is the PHP code snippet.
strtotime($random_hour = rand(00,23));
echo $random_hour . " Hour <br> ";
strtotime($random_min = rand(01,59));
echo $random_min . " Min <br> ";
$randomhourmin = $random_hour . ":" . $random_min;
echo $randomhourmin . "<br>";
This is the final SQL insert query.
$sql = "INSERT INTO schedule (staffID, cdate, starttime, endtime, dayoff) VALUES ('$rowID','$fDate','$randomhourmin','$randomhourmin','0')";
You can use below
$int= rand(1262055681,1262055681);
Also check mt_rand(), which is to have better randomness in the results:
$int= mt_rand(1262055681,1262055681);
To turn a timestamp into a string, you can use date(), ie:
$string = date("Y-m-d H:i:s",$int);

Submit timestamp to mysql

I am trying to add a timestamp to my database when I update a form, and for reason that I do not know, I am getting an error... and when just trying to insert the year, month, day I get "1988" inserted into my database. I use a similar timestamp elsewhere on the same site and it works fine. What am I doing wrong?
Note: yes I know I should be using mysqli and I'm vulnerable to sql injection. I plan on converting the entire site later in the year.
$homeScore = ((strlen($game['homeScore']) > 0) ? $game['homeScore'] : 'NULL');
$homeOdds = (str_replace("\xBD", ".5", $homeScore));
$visitorScore = ((strlen($game['visitorScore']) > 0) ? $game['visitorScore'] : 'NULL');
$visitorOdds = (str_replace("\xBD", ".5", $visitorScore));
$odds_timestamp = date("Y-m-d g:i:s A");
$sql = "update " . $db_prefix . "schedule ";
$sql .= " set odds_timestamp = " . $odds_timestamp . ", homeOdds = " . $homeOdds . ", visitorOdds = " . $visitorOdds . "";
$sql .= " where gameID = " . $game['gameID'];
mysql_query($sql) or die('Error updating odds: ' . mysql_error());
You have missing (single) quotes " . $odds_timestamp . "
that will need to be '" . $odds_timestamp . "' since it will contain characters that MySQL will complain about... being hyphens.
That is a string.
Now, if any of your other variables are also strings, they too need to be quoted as shown.
I.e.: '" . $string . "' as opposed to " . $integer . "
More on string literals:
https://dev.mysql.com/doc/refman/5.0/en/string-literals.html
Pay attention to Riggs' comments, one of which being:
"You would be best advised to make the datatype a DATETIME or TIMESTAMP as if you keep the VARCHAR it will make the data much more difficult to process later. Just change the date() to produce a legal MYSQL data format"
Using a VARCHAR won't fix it, as it still considered as a string literal for the column.
New comments by Riggs:
"You would be best advised to make the datatype a DATETIME or TIMESTAMP as if you keep the VARCHAR it will make the data much more difficult to process later. Just change the date() to produce a legal MYSQL data format. You can always add the AM/PM when you present the date time to any user. VARCHAR date/time will really mess with your selection criteria later as well. Remember - Database for DATA, Browser for PRESENTATION"
You can use MySQL's NOW() function, which returns current datetime.
Without error message, Its difficult to say something.
or if you can print your query it will be helpful.
but try with.
odds_timestamp = '" . $odds_timestamp . "'
to make it explicit string.
Try adding a timestamp column in the database table with an on update set current timestamp clause.
Heres a simple example from MySQL Documentation:
CREATE TABLE t1 (
ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
Should take care of it and cut out the middle man. Win-win.

Cannot send a database timestamp through JavaScript but can send other values

I'm using PHP5, MySQL, JavaScript and Fusion Charts.
I have the following time value returned from a database: 2011-12-19 12:00:00
After taking it from the database, I try to pass it through a JavaScript strURL to get it to another page where I can make further database calls using this value. The problem I have is that the JavaScript fails whenever I send it through a date/time. I can send through any other value type and it works so the problem seems to be with the time stamp. I've tried converting it to string before it is passed (just to be sure it's not one already) and that doesn't work. I'm guessing it's to do with the characters within the value. Any idea how to get around this?
The database call in PHP and then sending fields into the JavaScript:
$strQuery = "SELECT unit, watts, time, device, siteid FROM inverter WHERE time = '2011-12-19 12:00:00' AND siteid = '842'";
$result2 = mysql_query($strQuery) or die(mysql_error());
if ($result2) {
while($ors2 = mysql_fetch_array($result2)) {
$thetime = (string)$ors2['time'];
$strXML .= "<set color='58ACFA' label='" . $ors2['device'] . "/" . $ors2['unit'] . "' value='" . $ors2['watts'] . "' link='javaScript:updateChart(" . $ors2['unit'] . " , " . $ors2['device'] . " , " . $ors2['siteid'] . " , " . $thetime . ")'/>";
}
}
And then the JavaScript function:
function updateChart(first, second, third){
//DataURL for the chart
var strURL = "FactoryData.php?factoryId=" + first + "&device=" + second + "&siteid=" + third;
FusionCharts("FactoryDetailed").setXMLUrl(strURL);
}
link='javaScript:updateChart(" . $ors2['unit'] . " , " . $ors2['device'] . " , " . $ors2['siteid'] . " , " . $thetime . ")'
This JavaScript becomes something like
updateChart(341, 454, 842, 2011-12-19 12:00:00);
The first three arguments are valid numbers (I assume the IDs are integers), but the fourth argument causes a syntax error. What you need to do is wrap it in quotes to make it a string:
link='javaScript:updateChart(... " , \"" . $thetime . "\")'
^^ ^^
Now the JavaScript should be like this:
updateChart(341, 454, 842, "2011-12-19 12:00:00");
You can either convert the date to a timestamp with something like
new Date('2011-12-19 12:00:00').getTime()
or encode it using encodeURIComponent('2011-12-19 12:00:00')
The latter is probably the better solution, as it works with all kinds of values, not only dates. You can use decodeURIComponent if you want to read the parameters on the client side, that should already be working fine on the server side.

Categories