
Psycho
Moderators-
Posts
12,161 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Psycho
-
No. There are lossless and lossy image compression formats. Both use different methods of storing the data. A RAW image format is one form of lossless image format that has distinct data for every single pixel along with it's color. That is why they are huge in storage space. A gif and jpg (typically) are lossy formats (substitute some fidelity to create small file sizes) but work very differently. A gif has a color palet that can only hold 256 colors. It then defines each pixel in the gif by those colors. I suspect it does some other calculations such as define the pixel at index 1, 1 then also sets a repeat number. E.g. if the first 20 pixels are all the same color, it only has to define the color of the first pixel and then another value for the repeater. A JPG allows for 16 million colors but it does it's compression using more mathematical processes. For example, it may shift the color of a pixel slightly in order to make the compression more efficient. What that really means is to verify the image before saving/using it. You can only do so much validation of the image before uploading it. Once it is initially uploaded to the $_FILES array, you an run whatever validations, modifications on them and THEN save them however you choose. I think the problem you are running into is that you are reading different bits and pieces of information, but not understanding the info or WHY you should do those things. It is possible to have a legitimate image that contains malicious code. And, depending on how you use the images on your site, you could potentially risk exposing your users. So, while you should be doing things to ensure what the user provided has a legitimate image extension and PHP can tell it is an image file, a best practice is to recreate the image to remove any potentially malicious content in the image. Here is an article that explains how these vulnerabilities exist: https://asdqwedev.medium.com/remote-image-upload-leads-to-rce-inject-malicious-code-to-php-gd-image-90e1e8b2aada
-
Your table with events has a start and end date. How are you wanting the data displayed in the calendar - only an entry on the start date? Also, can there be multiple events on the same date? The answer to those questions will probably dictate how I would do it. I think the easiest approach would be to query all the events for the given month at the beginning of the function and put them into an array. Then when outputting the TD for any given day, check if there are any events for the day - if so, include them in the output. I thought your code was hard to read/work with, so I modified it quite a bit <?php /*MAKES THE CONNECTION*/ include 'config.php'; $conn = mysqli_connect($servername, $username, $password, $dbname); // CHECK CONNECTION if (!$conn) { die("Connection failed: " . mysqli_connect_error()); } /*DRAWS CALENDAR*/ function draw_calendar($month, $year, $conn) { //Create timestamp for the 1st of the month $firstDayTimestamp = mktime(0,0,0,$month,1,$year); //Offset the starting date number to add empty days before the 1st of month $dayNo = -1 * date('w', $firstDayTimestamp) +1; $daysInMonth = date('t', $firstDayTimestamp); //Get the events for the current month $sql = "SELECT DAY(start_day) as day, id, name, phone, item, start_day, end_day, start_time, end_time FROM $tablename WHERE YEAR(start_day) = $year AND MONTH(start_day) = $month"; $result = $conn->query($sql); //Put results into an array $events = array(); if ($result->num_rows > 0) { // output data of each row while($row = $result->fetch_assoc()) { $events[$row["day"]][] = $row; } } //Start the calendar table $calendar = '<table cellpadding="0" cellspacing="0" class="calendar" border="1">'; //Create the calendar headings $headings = array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'); $calendar.= "<tr class=\"calendar-row\">\n"; foreach($headings as $heading) { $calendar.= "\t<td class=\"calendar-day-head\">{$heading}</td>\n"; } $calendar.= "</tr>\n\n"; //Create each week in the calendar while($dayNo <= $daysInMonth) { $calendar.= "<tr class=\"calendar-row\">\n"; //Create each date for the week for($dow=0; $dow<7; $dow++) { //Check if the $dayNo is within the selected month if($dayNo<1 or $dayNo>$daysInMonth) { $calendar .= "\t<td class=\"calendar-day-np\"> </td>\n"; } else { //Code to create content for the given day $calendar .= "\t<td class=\"calendar-day\">"; $calendar .= "{$dayNo}"; //Add any events here if(isset($events[$dayNo])) { //Create outpout for each event on the current day foreach($events[$dayNo] as $eventAry) { $calendar .= "<div>{$eventAry['name']}</div>"; } } $calendar .= "</td>\n"; } //Increment the date $dayNo++; } $calendar.= "</tr>\n"; } //Close the calendar table $calendar.= '</table>'; return $calendar; } ?> <html> <body> <?php echo draw_calendar(1, 2021, $conn); ?> </body> </html>
-
I guess I'm still missing something. A user is on the "backoffice" page and they perform some action where you want to display a set of results in a new page "frontoffice" - is that correct? If the "frontoffice" page is opened from the "backoffice" page, then you can set a target on the "frontoffice" page. Then whenever the page is opened from "backoffice" it will replace the contents in the window that "frontoffice" was loaded in. FYI: You can use javascript in one window/tab to control another window/tab, but there has to be something to identify that other window/tab. It's typically done when the 2nd window is opened from the first. If the two urls are opened independently of each other, I don't know how you can reference one from the other. But, if you are wanting to just refresh the contents, I think the approach I provided above is easier.
-
Your question is unclear. Are these "pages" both currently open by the same user? I.e. the user clicks a button in one browser window that refreshes the content in another window? Or, is the page with a button something that User A clicks to initiate a refresh in a different page being viewed by User B? Better yet, why don't you explain the problem you are trying to solve that you think that creating such a scenario would solve? It's also important to know if these pages are hosted under the same domain. Do you have control over the content in both pages?
-
How do I insert multiple checkbox data as 1 or 0 in multiple columns?
Psycho replied to ke-jo's topic in PHP Coding Help
You are using the "keys" from the user submitted data as the field names in your query! DO NOT DO THIS! Never trust the data from the user. Just because you provided the field names in the form does not mean that the user will submit that back. The user could arbitrarily send any field names or even malicious SQL code to expose or corrupt your DB. -
You are passing a string as the parameter for "jobTitle" <a href="Careers Results.php?jobTitle=Animator"> Then you are forcing that string to be an integer and comparing it to the original value (a string). A string and the integer value of a string will NEVER be the same. if( (int)$id == $id && (int)$id > 0 ) { Assuming your job titles have an ID (integer) and a Name (string value), you should craft your links to pass the ID as the parameter and not the Name. Use the Name as the text for the link: <a href="Careers Results.php?jobTitleId=5">Animator</a> Then, on your receiving page you can use that value as you intended. Not, you do not need to use those comparisons. Just force the value to an integer and run your query. If the value is 0 or a negative value it will just return an empty result set - which you need to account for anyway: $jobTitleId = isset($_GET['jobTitleId']) ? (int)$_GET['jobTitleId'] : 0; $link = mysqli_connect('localhost','MYUSERNAME','MYPASSWORD','MYDATABASE'); // Connect to Database if (!$link) { die('Could not connect: ' . mysqli_connect_error()); } $sql = "SELECT * FROM careers WHERE jobTitle = {$jobTitleId}"; $result = mysqli_query($link,$sql); $row = mysqli_fetch_array($result); if(!$row) { echo "Record NOT FOUND"; } else { echo $row['jobTitle']; echo $row['jobDescription']; } Also, you really need to look into using prepared statements.
-
Your RegEx for email addresses is already flawed. Use built-in methods unless, as @gizmola stated, you have a use case that is not supported). As to your second question, if the error message you are referring to is one that is thrown from the DB, then you should absolutely have logic to show the message you define. Never expose DB errors to the user. You should always capture those and show a "friendly" message to the user that does not expose any details they could use to infiltrate the system.
-
I think what you are after is having the course ID be the VALUE of the option (which is what is sent to the server) and the Course ID as the LABEL for the option. Also, only SELECT the field(s) you want in a query - do not use '*' $resultset = $conn->query("SELECT course_id, course_name FROM tbl_courses"); while($row = $resultset->fetch_assoc()) { echo "<option value='{$row['course_id']}'>{$row['course_name']}</option>"; }
-
Not "horrible". There are use cases where that makes more sense than labels. E.g. when designing a form for a mobile device where screen real estate comes at a premium.
-
For that matter, why have $obj2 at all! Just use $obj->Location where you want that value.
-
Before you do that, you can verify if that is the problem. View the source of the page where the full name is not displayed and see if it is there in the content, but in such a way that it is malformed. You originally stated " . . . he is adding descriptions to the photos via a back end form, if he uses an apostrophe as in O'Sullivan for example, when he saves the entry, the description text does not show at all." First, I think it would be unlikely that output of the descriptions would be within an attribute. It might make sense if using the ALT attribute for an image, but that isn't normally "displayed" on the page. Second, if the problem is something akin to what @Barand states, I would expect "O" (in O'Sullivan) to be displayed as the description. I would suggest first checking the database. Is the full value of the description saved? If yes, then you have a problem with how the output of that value is done. Is the field empty or only containing the value before the apostrophe? If so, then the problem is with saving that content (although you could still have an output problem once you solve that). My guess is that you have a problem in saving the data, but I would expect there to be failures if data with apostrophes were not being handled in the code. For example, if the description was one of the DB fields for images, then a malformed SQL statement would not save an image but not the description. So, I am thinking one of two things: 1) The descriptions are saved to a separate table after the image record is saved. In this instance the SQL to insert the description record could fail after the image record was saved. If errors are suppressed there may be no outward display of a problem. 2) The workflow involves creating the image record first and then adding a description value in that same record as a second use case. In this scenario, the first record would save the image record. But, when attempting to update the image record with a malformed query it would fail. Again, if errors are suppressed, there may be no indicator that there was a problem.
-
I see no "link" in your code. I assume that the function l() is creating the links. You could find that function and modify it to take an additional (optional) parameter for the class. Then modify the code to insert that optional parameter value as the class. EDIT: Or do what @requinix said.
-
Create an array from prepared statement result
Psycho replied to Adamhumbug's topic in PHP Coding Help
You previously stated Based on that comment, this might make more sense: while ($stmt -> fetch()) { $users[$role][$id] =[$fn, $ln]; } You will then have a multidimensional array in a logical format based on the data, like this: array ( [Chef] => ( [8] => ('FName', 'LName') ), [Manager] => ( [15] => ('jon', 'smith'), [2] => ('Chelsea', 'Hockley'), ) ) You could then iterate over the results something like this foreach($users as $role => $roleUsers) { //Can add a header for each role here foreach($roleUsers as $userId => $userData) { //Within this loop have the following variables: // - $role // - $userId // - $userData['user_firstname'] // - $userData['user_lastname'] } } -
The title of your post was with regard to how much mocks should be utilized in Unit Testing. But, in your post you state you feel there is a lack of Black Box testing. Black Box testing is a form of User Acceptance Testing, not a form of Unit Testing, so the title and the content of your post are contradictory. With regard to Unit Testing, there is no "correct" amount that should or should not be comprised of mocks (in my opinion). It should be dependent upon what it is being tested. Now, if your question is really about whether Unit Testing (with or without mocks) replaces the need for Black Box testing, then the answer is No: Unit Testing and User Acceptance Testing are on opposite ends of the spectrum. Micro vs Macro.
-
With all due respect, I'm not going to try and learn your code and THEN generate what the output would be to determine what the problem is. We don't have your database to try and create the HTML that would be generated from that code. If you have a problem with the HTML that is generated, you should first look at the HTML. Then, once you find the problem, you can go back to your code that generates the HTML and determine the fix. Create a complete page with a few records and then post the HTML. I assume you have certain style properties on one or more divs to implement the scroll bar, but I dont' see that in your code. So, it's hard to know what the real problem is. I do however, see things that are wrong in the code There are no opening/closing TR tags for the header cells There is no closing tag for the TBODY opening tag There are TWO closing TABLE tags (for the one table) There is an extra closing DIV tag compared to the number of opening DIV tags you have posted
-
Not so much about "need be" as it is you "should be". As I said, an auto-increment field will probably work in most situations, but if you have a date field you should absolutely be using that. It's about using good programming techniques. For example, how records are created/managed could change (especially in large projects with many developers). There could be logic that allows a record to be "replaced" with a new record that simply changes the existing record and sets a new "created date". Sorting by the ID would then have that record display out of sequence. And understand that is just an example, there could be any number of reasons why the sequence of the id would not be the creation order - either due to business rules or other bad practices.
-
So, the 'absents' for a particular record (in your example 30) is the sum of all absents where the RecNo is less than or equal to 30? SELECT SUM(Absents) FROM [table_name] WHERE RecNo <= 30 That will give you the total Absents for a single entry. But, if you want a query to return multiple records showing the Absents " . . . at each level of entry", I think the only solution is a sub-query - which would be very inefficient in this case (if ONLY doing in SQL). I would highly suggest querying for all the relevant records and calculating the Absents at each level in code.
-
@kicken's answer is "correct", but I would highly advise against using such a general function. While that function is correctly using a prepared statement and protecting the $sid value, you cannot use prepared variables for table/column names. This leaves open the possibility for that function to open a potential exploit depending on how it is called. A function/method should be secure on its own without having to worry about how it is called. While prevailing logic is to write code once (i.e. don't build duplication functionality) when dealing with data it is typical to have explicit setter/getter functions/methods for scenarios such as this.
-
To add some clarification, when there are multiple ORDER BY conditions, the query will order by the first condition. Then, if there are records with the same value in that first condition, then it will sort those records by the second condition. And so on through all conditions. I.e. the second (subsequent) condition(s) only apply when two records have the same value for the first (preceding) conditions. As @cyberRobot stated, your query will first sort all records by the project_id. Then, if any records have the same project_id (a scenarios I expect would never occur), then it would sort those records would be sorted by the featured value. I would also add that I assume project_id is an auto-increment primary key field. Using that for sorting by newest/oldest will "probably" work in most instances, but is a poor implementation. There are many scenarios where such a field would not necessarily be in order of when the records were created. I would suggest having a "date_created" field that is auto-populated when new records are created and using that for sorting by newest/oldest
-
adding multiple rows into databse incrementing one field.
Psycho replied to nook6's topic in PHP Coding Help
Heck, I'd still go with the original "simple" auto-increment field solution. All that really matters is that the numbers are unique for each raffle. What does it matter if the number are not sequential! E.g. Raffle #1 has four tickets sold with four unique numbers: 1, 4, 7, & 8. -
Here is the line you would need to modify if ($_POST['submit'] && $human == ‘wednesday’) {
-
Create new line of dynamically populated content from button
Psycho replied to Adamhumbug's topic in PHP Coding Help
Then you need to do that first. Your form, as it is, doesn't even have all the data you need. For example, you are outputting the fields associated with a date, but the "groups" of fields have nothing to indicate which date they are with. So, if the user submits you will have no way to know what date to use when inserting/updating the records. You should absolutely work on building a working process before adding the javascript. I foresee many other posts from you trying to work through what should be trivial issues if you just @Barand's code as-is without determining the naming/structure of the fields. Plus, since you are copying only a manager OR chef line (not the block), I think the AJAX call is unnecessary since all the data you need is within the DOM object. First, you need to determine how you will logically "group" fields and ensure each group has the necessary data. E.g. how do you know which name/start/end fields go together. You will also need a hidden field to identify the date in each group of fields. Plus, if you are dealing with the ability to edit existing records as well as add records, you need an identifier to know which groups of fields are associated with existing records. If done quickly without much thought the act of copying a row can become quite complicated. If done with some thought, it makes the job much easier. Below is a working example that does not use AJAX. Note that the "rec_id" field is to be populated with the ID when creating the page for the existing records. Entries added with the "Add" button will have an empty value. So, on the page that receives the form submission, you would use that data to determine whether to perform an UPDATE or INSERT. <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> $( function() { $(".addRow").on( "click", function() { //alert('test'); //Make reference to the parent row var parentRow = $(this).closest('tr'); //Create a copy of the parent row var newRow = parentRow.clone(); //Remove values in the Cloned Time & ID fields $(newRow).find('input[name^="start_time"]').val(''); $(newRow).find('input[name^="end_time"]').val(''); $(newRow).find('input[name^="rec_id"]').val(''); //Select the name based on parent record and disable $(newRow).find('select[name^="name"]').val($(parentRow).find('select[name^="name"]').val()); $(newRow).find('select[name^="name"]').prop('disabled', true); //Remove the add button $(newRow).find('button').remove(); newRow.insertAfter(parentRow); return false; }) }) </script> </head> <body> <form> <table id='staffOrderTable' class='table table-striped table-bordered mt-3 text-center'> <tr> <th class='table-dark' colspan='3'>Tuesday - 24th December 2019</th> </tr> <tr> <th class='' colspan='3'>Management </th> </tr> <tr> <th class='col-4'>Name</th> <th class='col-4'>Start Time</th> <th class='col-4'>End Time</th> </tr> <tr> <td> <input type='text' name='date[]' value='2019-12-24'> <input type='text' name='rec_id[]' value='21'> <select class='custom-select managerSelect' name="name[]"> <option value='5'>Manager A</option> <option value='9'>Manager B</option> <option value='2'>Manager C</option> </select> </td> <td><input class='form-control' type='' name='start_time[]' value='6:00'></td> <td><input class='form-control' type='' name='end_time[]' value='14:00'></td> <td><button class='addRow'>Add Row</button></td> </tr> <tr> <th colspan='3'>Chefs</th> <tr/> <tr> <th class='col-4'>Name</th> <th class='col-4'>Start Time</th> <th class='col-4'>End Time</th> </tr> <tr> <td> <input type='text' name='date[]' value='2019-12-24'> <input type='text' name='rec_id[]' value='54'> <select class='custom-select chefSelect' name="name[]"> <option value='8'>Chef A</option> <option value='4'>Chef B</option> <option value='7'>Chef C</option> </select> </td> <td><input class='form-control' type='' name='start_time[]' value='7:00'></td> <td><input class='form-control' type='' name='end_time[]' value='12:00'></td> <td><button class='addRow'>Add Row</button></td> </tr> <tr> <th class='table-dark' colspan='3'>Tuesday - 24th December 2019</th> </tr> <tr> <th class='' colspan='3'>Management </th> </tr> <tr> <th class='col-4'>Name</th> <th class='col-4'>Start Time</th> <th class='col-4'>End Time</th> </tr> <tr> <td> <input type='text' name='date[]' value='2019-12-25'> <input type='text' name='rec_id[]' value='33'> <select class='custom-select managerSelect' name="name[]"> <option value='5'>Manager A</option> <option value='9'>Manager B</option> <option value='2'>Manager C</option> </select> </td> <td><input class='form-control' type='' name='start_time[]' value='6:00'></td> <td><input class='form-control' type='' name='end_time[]' value='14:00'></td> <td><button class='addRow'>Add Row</button></td> </tr> <tr> <th colspan='3'>Chefs</th> <tr/> <tr> <th class='col-4'>Name</th> <th class='col-4'>Start Time</th> <th class='col-4'>End Time</th> </tr> <tr> <td> <input type='text' name='date[]' value='2019-12-25'> <input type='text' name='rec_id[]' value='74'> <select class='custom-select chefSelect' name="name[]"> <option value='8'>Chef A</option> <option value='4'>Chef B</option> <option value='7'>Chef C</option> </select> </td> <td><input class='form-control' type='' name='start_time[]' value='8:00'></td> <td><input class='form-control' type='' name='end_time[]' value='16:00'></td> <td><button class='addRow'>Add Row</button></td> </tr> </table> </form> </body> </html> -
Create new line of dynamically populated content from button
Psycho replied to Adamhumbug's topic in PHP Coding Help
You don't have to do this with JavaScript - although it would provide a better user experience. In fact, I think it is beneficial to build such functionality w/o JS to start and then add JS. But, I am unclear from your goal as to whether you are wanting to add management and chef rows independently or complete sections with both a management and chef line (or something else). Also, using a framework like JQuery is always a good idea. EDIT: I just noticed none of your input fields have names. Are you intending for the user to submit the form once filled out and do something with that data? I would assume so and in that case the naming of the fields is important if you are going to be dynamically adding fields. -
What you are calling duplicates are not, in fact, duplicates. I'm curious what made you think a UNION clause was needed? In the response to @Barand's query you showed a result set of five records each having a different gp_id value In other words, they are unique records. I can see that they contain much of the same data, but they are distinct records. What makes you consider them "duplicates"? I think your problem may stem from a schema problem. I see multiple things in what you are doing that don't make sense. For example, you are joining the user and updates tables using the name of the author? You would typically be joining tables based on IDs rather than arbitrary string values. Is the group_posts table for conversations between multiple individuals and are you adding a new record for each response in that conversation? What determines which records are form the same conversation?
-
My suggestion was just an example. It will work if implemented correctly. People want to see all the relevant code for a problem. It is incumbent upon the person with the problem to do the basic trouble shooting to determine the area of the code where the problem exists and provide that code. The person should also provide what the code is expected to do and what is IS doing differently than the expectation. I gave a potential explanation of why you would get duplicates if you are simply basing the additional records to get based on an index when ordered by date/time. When you are seeing duplicates - are there other records being added to the system that would be included in the user's feed? If so, that is likely why you are seeing duplicates. Here is an illustrative example: Let's say there are 6 records added from A - I. When you retrieve the first five records in reverse chronological order using LIMIT 0, 5 (which gets five records starting at index 0, i.e. 0 - 4) you will get I-E, because the query will see something like this (number in parenthesis represent the index of the records matching the criteria). Now, let's say a new record is added (J) THEN you attempt to get the next five records using LIMIT 5, 5 (i.e. indexes 5-9). You will get a duplicate of record E, because it will have moved from index 4 to 5. Based on your function totalUpdates() that returns five records based on an arbitrary $load variable to indicate the limit start index. I can't say that IS your problem, but it will be a problem if records are being added in-between the load calls. In any event, I suggest you add some logging to see what is going on. I would start by logging the calls to the totalupdates() function to verify that the $load value is what you expect (0, 5, 10, 15, etc.). I would also log the total number of records that match the conditions of the query (w/o the limit condition). That requires adding a second copy of the query with a count() instead of returning the results, but it would only be used for debugging purposes.