Psycho
Moderators-
Posts
12,157 -
Joined
-
Last visited
-
Days Won
129
Everything posted by Psycho
-
I'm not sure I follow what you are exactly trying to find. I see you gave some example input, it would have been helpful to see what you expect to be returned. Specifically, I'm not sure what you mean by "textblock". I *think* you mean where a line starts with 'sample' followed by however many lines until you find a line that ends with 'sample'. However, note that the word "sample" never appears in your text block. There is a word spelled "smaple" - I have no idea what that is. How you word #1 and #2 is confusing as well. Are you saying you want to find the first textblock which starts with "sample" and ends with "sample" and then find the NEXT textblock the same way, but the second one contains the keyword? Or does #2 mean the keyword is supposed to be in the first textblock?
-
You can turn on error reporting in your script by putting this at the top of the page error_reporting(E_ALL); https://www.php.net/manual/en/function.error-reporting.php
-
Short fuse? I've taken the time to respond multiple times providing the same information which you ignore because you've got some preconceived notions in your head that you can't get rid of. Think of it this way, someone is taking time out of their day to try and help someone for no reason other than goodwill - there is no compensation for their time. Yet, the person they are trying to help ignores/disregards the help being provided such that the person providing the help invests even more time and energy helping that person. So, who is the "nutter" in this scenario? The person that is attempting to help or the person that won't take the time to try and understand the help being provided? You are "terrible" at this because you are not taking the time to understand the process. Instead you seem to be throwing things at the wall to see what will stick. Let's try one more time: Your requirement is to delete a record three days after the user performs some event (which I assume is a logout). Is this correct? 1) You first need to perform an action when the user selects the option to logout. As stated many times, you would want to set a datetime/timestamp value for the record. STOP HERE. Is there something about that statement that you do not 100% understand? Do you understand why the record would need to be updated and why we would use a datetime/timestamp value for that update? If you are not 100% clear, ask a question about that. You've previously provided info that when this action takes place the user_id is available in the session data. So, we would accomplish the above action like so: //Create a prepared statement with placeholder for the user_id of the record to be updated $stmt = $dbc->prepare("UPDATE users SET logout_datetime = NOW() WHERE user_id = ? "); //Bind the user_id value to the prepared query and execute it $stmt->bind_param('i', $_SESSION['user_id']); $stmt->execute(); STOP HERE. Do you understand all of the code above? If not, ask a question about what you don't understand or look at the manual for any function you don't understand. 2) Now that users will have a datetime/timestamp value set when they log out, there needs to be a separate process that will delete the records after three days. To accomplish this, you would create a separate script which will need to be executed on a regular basis (e.g. daily). You will need to check your host options o how to do this. Typically these will be called CRON jobs. You basically set up a scheduled task to run a script at a predetermined interval. STOP HERE. Do you understand what was just stated? If not ask a specific question. If you don't know how to create a CRON job, you need to go into your hosting options, check help and/or contact support. Once you know how to create a CRON job, you just need to create the script that will run every day (or whatever time interval you choose). Since we have a datetime/timestamp of when users have logged out, a single query can be executed to delete all records where that value is > 3 days (as has been provided previously) $query = "DELETE FROM users WHERE logout_datetime < (DATE(NOW()) - INTERVAL 3 DAY)"; //No user_id $stmt = $pdo->query($query) STOP HERE. Do you understand what that query is doing and why user_id is not needed? This is my last attempt. I hope you will READ the above information and attempt to comprehend it. If you have any questions that show that you have put some energy into trying to trying to figure this out instead of just haphazardly writing new code, I will try to answer. Otherwise, I which you all the best in your endeavors.
-
I'm trying really hard now not to start using foul language. You are doing exactly what I said before. You aren't reading what is posted - as in looking at it critically and trying to comprehend what is being provided. Instead you seem to be fixated on some erroneous logic and are trying to fit the responses into that. Do you understand that what you want to accomplish has two separate processes (as I've explained multiple times)? If you have a question about what I posted ask a specific question about it instead of coming up with some nonsense question.
-
I think you are misunderstanding something - why is there a placeholder for id in the delete query? Go back and read my last post and pay attention to the very explicit details I posted for steps #1 and #2. Then go back to the post I made before that where I provided example queries for #2 and neither included a user_id. I think the problem is that you have an incorrect assumption in your head and every new piece of data you are trying to align it with that assumption. You need to read the responses and not assume. It really isn't that difficult. I will try one more time to explain this. 1. When a user selects an option to logout you will run a process to set a logout time for that specific user. In this case you will get their user id from the session and run an UPDATE query similar to what Barand provided using the user_id to determine which records to apply the update to: $stmt = $dbc->prepare("UPDATE users SET logout_datetime = NOW() WHERE user_id = ? "); // prepare query with placeholder (?) for id value $stmt->bind_param('i', $_SESSION['user_id']); $stmt->execute() 2. Run a scheduled task to delete the records of ALL USERS where the logout_datetime is more than 3 days in the past. It will only use the logout_datetime field to determine which records to delete (i.e. no user_id). Also, there is no need to use a prepared statement since this does not use any input variables. $query = "DELETE FROM users WHERE logout_datetime < (DATE(NOW()) - INTERVAL 3 DAY)"; //No user_id $stmt = $pdo->query($query)
-
As I understand your requirements, there appears to be some process that is initiated by the user that initiates the code you are currently working on. I assume it is a logout process, but you have not explicitly stated. Right now, the code is deleting the record, but you later stated . So, there needs to be TWO separate events: One to set the timer and one to delete the records. 1) Modify your existing code for the event so it sets the datetime/timestamp value for the user initiated action - this will occur for each user individually. 2) Create a process that runs daily (or whatever interval you decide) which will delete the records associated with all users where the applicable time period has elapsed. This is a single query that executes for all applicable records at once. Do NOT name your field datetime. That is a field type in MySQL and is a "reserved word". You would have to take special steps to prevent errors in your query if you have a field named using a reserved word. Give it a name that is representative of what it is: expirationDate, logoutDate, etc.
-
@tryingphp you need to slow down. If you don't understand something, figure it out first or ask a question. It appears you are just copy/pasting code without understanding what it does and then throwing random edit at it. I don't see that you even acknowledged the original problem which @Barand and @ginerjm both stated. Your original query was simply deleting every record where the value in the user_id field was equal to itself. You wanted to delete those records where the user_id was equal to $_SESSION['user_id']! Your original query would look like this $sql = "DELETE FROM users WHERE user_id = $_SESSION['user_id']"; But, don't use that - it is unsafe. You should use prepared queries such as Barand provided (do some research, way too much info to explain in a forum post). I only provided it in that fashion because it is easier to visualize what was wrong. Then, Barand provides a different, more efficient solution and you try to integrate it into your current solution. Let me break it down for you: 1. Create a new field in the DB - I would suggest a timestamp or datetime. I assume this is a for a logout function, so the field could be logout_datetime. If not, name it something appropriate for the function being performed. 2. When the process is initiated, perform an update query (using the session value = user_id) and set the value in that field to either A) the current datetiem using NOW() or B) to the datetime three days in the future. I would use option A (explained below) 3. Have a scheduled task that runs each day/hour/whatever which will delete all the records based on the datetime value in the field above. If you go with option A, then this delete function would need to delete all records where the value is < today-3 days. Something like this: DELETE FROM users WHERE logout_datetime < (DATE(NOW()) - INTERVAL 3 DAY) If you go with option B, the logout function would run an update query similar to the above, but the interval would be +3 and the delete query would look something like this: DELETE FROM users WHERE logout_datetime < NOW() In either case, Do not use a query based on the values being equal. If the process was to ever not run one day you would have records that would exist indefinitely. So, you want to delete all records that are 3 or more days old. The reason I would go with option A is that if you ever needed to change the logic on the time period on which to delete, you could change it in the DELETE query and it will apply to all existing records. Otherwise, if you put the 3 day period as part of the update query, any changes would only apply to new records.
-
What's the proper way to do "SORT BY" selection options?
Psycho replied to imgrooot's topic in PHP Coding Help
I think you are greatly over-complicating the building of the Label for the select options. If you need different data for the value and the label, the approach I provided gives you more flexibility to explicitly set those two values. As per my signature: In any case, when I run the code I provided it works without error (assuming values are given for $offset & $total_records_per_page, which were assumed set somewhere in your code). I'm guessing you modified the code I provided or didn't fully implement it. Based on the error, I would say you updated the foreach() code, but did not update the array with the new structure. -
What's the proper way to do "SORT BY" selection options?
Psycho replied to imgrooot's topic in PHP Coding Help
There are many ways. How I would do it would depend on factors that would require me knowing more about how the application is used, which I'm not going to invest time into. So, I'll give one solution. Change the array to be multi-dimensional such as shown below. If you haven't already caught on, the data for this array which defines the sorting parameters (key, label, fields and direction [ASC/DESC]) could be moved to the DB. $sortValues = array( 'newest' => array( 'label' => 'Newest', 'sortSql' => 'projects.date DESC' ), 'oldest' => array( 'label' => 'Oldest', 'sortSql' => 'projects.date ASC' ), 'lowest-price' => array( 'label' => 'Low to High', 'sortSql' => 'projects.price ASC' ), 'highest-price' => array( 'label' => 'High to Low', 'sortSql' => 'projects.price DESCC' ) ); //Create select options $sortByOptions = ''; foreach($sortValues as $sortKey => $sortData) { $selected = (isset($_GET['sort_by']) && $_GET['sort_by']==$sortKey) ? 'selected="selected"' : ''; $sortByOptions .= "<option value=\"{$sortKey}\" {$selected}>{$sortData['label']}</option><br>\n"; } //echo $sortByOptions within the <select> field //Determining the sort logic to use in query if(isset($_GET['sort_by']) && isset($sortValues[$_GET['sort_by']])) { $sortSql = $sortValues[$_GET['sort_by']]['sortSql']; } else { //Default if no user selection or selectio is invalid $sortSql = $sortValues['newest']['sortSql']; } //Use $sortSql in query after the ORDER BY clause $query = "SELECT images.image_id, currency.currency_name, users.username, users.user_id, projects.* FROM projects LEFT JOIN images ON projects.project_id = images.project_id LEFT JOIN currency ON projects.currency_id = currency.currency_id LEFT JOIN users ON projects.user_id = users.user_id WHERE projects.category_id = :category_id AND projects.publish = :publish ORDER BY {$sortSql} LIMIT $offset, $total_records_per_page"; -
What's the proper way to do "SORT BY" selection options?
Psycho replied to imgrooot's topic in PHP Coding Help
That's better, but you are hard-coding the list of select options and then use a series of hard-coded if/else statements that are dependent upon those hard coded values. This makes it difficult for maintaining your code. Create one source of truth for your sorting options, then use that source of truth to both create the select options and generate the SQL code for sorting. Here is a down an dirty example where the sorting properties are in an array of valid values. You could have more complex logic by utilizing a switch statement (I would not use a bunch of if/else statements) <?php $sortValues = array( 'Newest' => 'projects.project_id DESC', 'Oldest' => 'projects.project_id ASC', 'Lowest Price' => 'projects.max_budget ASC', 'Highest Price' => 'projects.max_budget DESCC', ) //Create select options $sortByOptions = ''; foreach(array_keys($sortValues) as $sortLabel) { $selected = (isset($_GET['sort_by']) && $_GET['sort_by']==$sortLabel) ? 'selected="selected"' : ''; $sortByOptions .= "<option value=\"{$sortLabel}\" {$selected}>{$sortLabel}</option><br>\n"; } //echo $sortByOptions within the <select> field //Determining the sort logic to use in query if(isset($_GET['sort_by']) && isset($sortValues[$_GET['sort_by']])) { $sortSql = $sortValues[$_GET['sort_by']]; } else { //Default if no user selection or selectio is invalid $sortSql = $sortValues['Newest']; } //Use $sortSql in query after the ORDER BY clause -
What @requinix said foreach ($spanNodeList as $spanNode) { $spanNode->parentNode->removeChild($spanNode); }
-
Setting option in a select dynamically with PHP
Psycho replied to Adamhumbug's topic in PHP Coding Help
You obviously need to retrieve the user's previously selected value first. You could do that independently (in a separate query) OR combine it into the query you have to retrieve the options. Note, don't use "SELECT *" = only query the fields you are using. Also, your logic is over-complicated. The first if() statement will always return true even if the query fails since the condition is to check if the results of the query can be assigned to the variable $result. Also, there's no reason to check if the results have more than 1 row before running the while loop. If there are no records, the while loop would not run. If you pull the selected option independently, you could use something like this $userSelection = //Some value retrieved from DB $sql = "SELECT role_id, role_name FROM ssm_role ORDER BY role_name ASC"; $result = mysqli_query($conn, $sql) if(!$result) { //Add error handling } else { while ($row = mysqli_fetch_array($result)) { $selected = ($row['role_id']==$userSelection) ? ' selected="selected"' : ''; echo "<option value='{$row['role_id']}'{$result = mysqli_query($conn, $sql)}>{$row['role_name']}</option>"; } } Or you could change your query to pull the roles and the users selection at the same time $sql = "SELECT r.role_id, r.role_name, us.userSelectedRoleId FROM ssm_role r JOIN table_with_user_selection us WHERE us.user_id = $userID ORDER BY r.role_name ASC"; Then, using the same loop above, change the $selected code to this $selected = ($row['role_id']==$row['userSelectedRoleId']) ? ' selected="selected"' : ''; -
From Wikipedia
-
One other problem I see: It appears there is a single submission_id whether the user submits one or multiple pets (since it is not included in the JSON data). But, the current code is using that submission_id to determine duplicates. If a user was to submit two records. I think you would end up with ONE in the database. The first record submissions would be created as a new record. But, when processing the second submissions, the code would "assume" it was a duplicate because there is an existing record with the same submission_id (i.e. the first record) and it would perform an UPDATE. I'm not sure where/how the submission_id is being created/managed. But, I think you'll need to change that logic.
-
Maybe I am missing something, but I think there is a simpler solution. The intent appears to be to get a list of IDs that DO NOT match those two conditions. Rather than creating JOINs or Sub-Queries, why not just change the conditions to be a positive check rather than a negative check. So, instead of looking for records that do not match BOTH those conditions, just look for records where either (i.e. OR logical operator) of those conditions are not true by switching the operators from <= to > and the other from >= to <. This should get the same results in a simpler fashion: SELECT RentID FROM rental WHERE Dispatch > "2019-10-08" OR Dropoff < "2019-10-02"
-
OK, there could be multiple changes needed. SO, I would start by running a test. Edit a record in the DB (change a value of 1 to 1.5) and does that record correctly sort between 1's and 2's on the pages where it is to be sorted? If yes, then you only need to solve the problem of where that value is INSERTed/UPDATed in the database. I don't see any such queries in the code you have provided. Look for any code with queries that do INSERT or UPDATE for and which include the sort field. My guess is you will see something similar to the process I see used in the above queries where p.products_id = '" . (int)$_GET['pID'] . "' But, of course this would be for the sort field. Change "(int)" to "(float)" in those instances. That may be all that is needed. If not, we would want to trace back to where the variable used for that field may be modified before being used in the query.
-
@Barand I was thinking the same thing - just build the array the way you need it. But, it's also possible that the loops at the top are just to create some mock data as it would be returned from a DB query and the reason he needs a convert() function is to then turn those DB results into a logically structured array. Either solution could have very easily been provided in the very first response if the problem was explained clearly. But, it's impossible to know without consulting the crystal ball 🔮 EDIT: Also, I'm not sure when it changed, but you can define a "child" array element directly w/o having to define the parent elements first. This used to produce a warning, but has not been the case for a long time now. So, while I used to do just as you did above (and sometimes still do), that can be simplified to just this foreach (range('A', 'D') as $section) { for ($row = 1; $row < 3; $row++) { for ($seat = 1; $seat < 4; $seat++) { $srs['sections'][$section]['rows'][$row]['seats'][] = $seat; } } }
-
Please read that statement back to yourself. I really don't care if someone uses poor grammar or has misspellings - as long as what they are stating is understood. I don't understand that. I *think* you might be stating that the variable $srs is not being recognized in the convert_array() function. If so, why did you not post the error? It will tell you the line number that the error was thrown on. I ran the code you posted and it executed w/o error - but it is not a multi-dimensional array as you last posted. I have the following in the signature of my posts "The quality of the responses received is directly proportional to the quality of the question asked." I find it rather annoying when people come to ask for free help and can't take the time to clearly define what it is they want. I still don't know what you are wanting to achieve. Are you wanting to convert the single-dimensional array to a multi-dimensional array? If so, why don't you create the array as multi-dimensional to begin with? Also, why does each successive for() loop use the ending value from the previous loop as the stating value? I see no logical reason why "Section 1" would have rows 1-5, "Section 2: would have rows 2-6, "Section 3" would have rows 3-7, etc. None of this makes any sense. No. $srs is passed to the convert_array() function which simply returns back the original value passed into it. The use of that function with $srs is used as the parameter for the output() function. The end result is that an array identical to $srs is passed into the output() function - which simply dumps the contents of the array to the screen. I don't see anywhere he is trying reference $srs in the convert_array() function. The code "works" without errors.
-
Yeah, you need to provide clarification. I';ve read your code and your request and am not sure what you are trying to accomplish. I see that you are creating some "random" records to specify "seat" which include three properties: section, row and seat no. Are you wanting to condense these so you can show a series of seats in the same section/row? E.g. "Section 4, Row 8, Seats 6-10"? Or are you just wanting to output each record in a human readable format: "Section 4, Row 8, Seats 6", "Section 4, Row 8, Seats 7", "Section 4, Row 8, Seats 8", etc.? If it is the former, I would structure the array differently. If the latter, then just loop over the array foreach($arrayVar as $seat) { echo "Section: {$seat['section_name']}, Row: {$seat['row_name']}, Seat: {$seat['seat_name']}<br>"; }
-
OK, so Google does have a product that you might be able to tie into: Vision AI. I saw in a forum post that there is an enhancement request to detect image orientation, but I don't know if it is implemented yet. It does have face recognition and I would assume that would return a rectangle. So, if there are faces in a photo, the correct orientation should have the long sides of the rectangle(s) be vertical. But, you could inadvertently turn the picture upside down. In any event, trying to explain how to use such a service is beyond the scope of a forum post. Good luck.
-
OK, let's break this down. You state you want to automatically change the orientation of an image when it is submitted. First of all, I don't see anything in that code related to image submissions. I would expect to see data relate to $_POST/$_FILES arrays on a page that handles submissions. OK, but let's say we have that code. How are you planning to determine the correct orientation to change to automatically? Functionally, it is not 'difficult' to change the orientation of a photo in PHP, but there is no functionality in PHP to "look" at a photo and know how to correct it. What you could do is allow a user to upload a photo and then present the photo back to them so they can determine if the orientation is correct. If not, give them the ability to "fix" it. This could be as simple as providing three buttons: rotate 90, 180, 270 which would just perform that one action OR you could provide some robust javascript front-end tools to 'manipulate' the image on screen and allow them to submit those changes. That would require PHP code to actually implement all the options you allow on the front-end. Here is the PHP manual for the image rotation function. But, as stated above, you have to give the code some way to "know" how to rotate it correctly. I'm sure there are some third party applications (for $$$) that you could implement. Or, Google may have something for free you could tie into to try and determine the correct orientation. But, none of that would be simple.
-
What you are wanting to do is "spoof" the from address. While there can be some legitimate business needs to do this, it can create problems that are difficult/impossible to resolve. Spoofing the from address is rather simple and is something that spammers/scammers have been doing for many years now. E.g. you might be sent an email from representative@yourbank.com as a phishing attempt. The fact that the from address looks to be a legitimate email from your bank gives the email some credibility. Because of this, there are an array of different protections that can be in place to prevent/hinder this. The crux of the issue is that you want to send an email from "user@usersdomain.com" but it is being sent though your form which is going to send it through the email server that you have configured for your form - in this case gmail.com and using the credentials of a gmail account. Generally, an email should be sent through the SMTP server that is responsible for the domain of the sending user (or through an SMTP server that has been identified as an authoritative server for that domain). You cannot control the authoritative servers for domains you do not own. Then, there can be protections on the receiving end: either in the SMTP servers or in third-party services. When an email comes in the system may do a reverse-lookup to ensure the email came from an authoritative server. If not, it gets dropped. To put it simply, you can try it. It may not work for all emails (especially if they are being sent to different domains) and there is no guarantee that it won't stop working one day because you are performing the same action as a scammer would. Having said all that, when sending an email you can specify the sender information within the headers. Here is an example of the header in a sample script of mine using PHP's mail function (this uses a "friendly" name :in addition to a specified from email address $to = 'recipient@recipientdomain.com'; $subject = "Subject of the email"; $message = "Here is body of the email message"; $headers = 'MIME-Version: 1.0' . "\r\n"; $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n"; //From info $headers .= 'From: Bob Smith <bob.smith@bobsmithsdomain.com>' . "\r\n"; $headers .= 'Reply-To: Bob Smith <bob.smith@bobsmithsdomain.com>' . "\r\n"; $headers .= 'X-Mailer: PHP/' . phpversion(); $message = "Here is the message"; mail($to, $subject, $message, $headers); For your function, I suspect you would do it like this: $headers = array( 'From' => $_POST['EmailAddress'], 'To' => $to, 'Subject' => $subject ); But, for the reasons stated above, I would not advise this. "System" emails should be coming from the system/application. There are other ways to allow the recipient to respond to the requester.
-
So, now you are going to post the REAL code? How nice of wasting people's time. You still haven't done what has been suggested multiple times - output your variables so you can SEE what they are. Instead of putting your query string directly in the prepare() statement, create it as a variable. Also, the full query that you are now showing us could be the problem. Even if there is matching data an error in the JOIN criteria could prevent any results. Replace this for the relevant section in your code and look at the results to see if the query and param values are what you think they are. // // FINDTOTAL RECORDS IN SEARCH RESULTS // $placeholderStr = join(",", $placeholders); $query = "SELECT COUNT(*) as tot FROM ( SELECT id FROM ( SELECT v.id , v.title , GROUP_CONCAT(tag SEPARATOR ' ') as alltags FROM product v JOIN product_tag t ON v.id = t.product_id GROUP BY v.id ) v JOIN product_tag t ON v.id = t.product_id WHERE tag IN ({$placeholderStr}) GROUP BY id HAVING COUNT(t.tag) = ? ) found;"; echo "<b>Query:</b><pre>{$query}</pre><br>\n"; echo "<b>Params:</b><pre>".print_r($params, true)."</pre><br>\n"; $res = $db->prepare($query); $res->execute($params);
-
First, I would strongly suggest that you first use more appropriately named variables. Don't create a generic variable and then try and reuse it. What does "$params" represent? Parameters obviously, but parameters for "what"? In this case $params is an array that keeps getting additional values appended to it - and those values are logically different "types" of values. Also, a prepared query will expect an array with the same number of parameters as placeholder in the query. Second, output your variables to the page to "see" what they contain. $params does not contain what you think it does when you are using it.
-
//I broke out the code into multiple lines for readability and maintainability function insertReferences($text) { $regEx = "#(\d{3})\.(\w)#is"; $format ='<span class="btn btn-link" data-target="section${1}" onclick="showPage('section${1}')" data-parent="#page">${1}.${2}</span>'; return preg_replace($regEx, $format, $text); }