Jump to content

Psycho

Moderators
  • Posts

    12,146
  • Joined

  • Last visited

  • Days Won

    127

Everything posted by Psycho

  1. OK, I need to correct myself I was mixing up some of the techniques. I went back and reviewed a training session about account management on Pluralsight (great training material). Troy Hunt (the author) recommends the following approach to prevent account enumeration: Upon submitting a form to register an account provide the user a common message along the lines of "Your registration has been processed, an email has been sent to complete your account". They would get this message in the case of a successful registration or a duplicate username/email. 1. If the registration was successful, the user receives an email to confirm the account 2. If there was a duplicate, send an email to the user that the account was already registered. Of course, this requires a more complicated process of user registration.
  2. Agreed, you should let the user keep trying to register until eventually, in desperation, they try a different user name. At that point, when it works, they realize that the problem was a duplicate username. But at least, you didn't tell them. Just to add some clarity here. @benanamen is correct in that you don't want to create a system that allows a malicious user to easily ascertain usernames from your system - specifically in mass. And, @Barand is correct that it makes no sense on a registration page to NOT tell a user you could not create their account because they chose a user ID that is already in use. The problem to solve is to prevent a malicious user from farming the system to create an inventory of all your users through automation. The malicious users could then iterate through all the users trying different common passwords until they get a match. If this is important, there are various solutions that can be employed: 1. CAPTCHA or some other means that requires human interaction 2. Slow them down. Introduce a delay of a few seconds or more in the registration process which would make the time to get a full list lengthy even with automation. Easy to implement and would not be noticed by users. (as long as it is not excessive) 3. Keep a log of requests by IP, session, or some other means. If those attempts exceed a threshold you set then either prevent new requests or introduce an even longer delay. More difficult to implement. There are other ways (such as using analytics) to programatically detect malicious submissions. But, you need to determine the risks to your application and the costs associated with any potential data breach in order to weight how much effort to invest. EDIT: This is a registration page where a user is creating an account - not an authentication page. You should never tell a user the reason you could not authenticate them (i.e. username not found or password wrong). But, that is not what this was about
  3. I guess you missed the update I posted in response to @requinix It now works for those previous dates as well as the years that end in "00". Tested from year 1 to 3000. I think that should be sufficient. I was really just interested in implementing a calculation to find the day of the week. I think I'll stick with using date() from now on.
  4. You're right. I was only considering future dates, but the same problem would occur in the year 2100. Apparently the problem stems from a flaw in the PHP logic for modulus which will return a negative number whereas most other languages only return a positive integer. I must fix this in case someone refers back to this post 80 years from now! I could define a custom modulus function to only return positive integers, but it's simpler for this process to just "hack" it by adding a hard-coded constant of 35 so the modulus of 7 will still be the same, but will never be negative. For those to whom it is not obvious, this is all sarcasm. I did this as a mental exercise and am not proposing that this is a preferred solution in any way. But, it does work function isFridayThirteenth($year, $month, $day) { $k = $day; $m = (($month+9)%12)+1; $C = floor($year/100); $Y = $year%100-(($m<11)?0:1); $W = ($k + floor(2.6*$m - 0.2) - (2*$C) + $Y + floor($Y/4) + floor($C/4) + 35) % 7; return ($W==5 && $day=13); }
  5. I didn't realize this was a challenge question. You're all being lazy relying on the date function 😁 function isFridayThirteenth($year, $month, $day) { $m = (($month+9)%12)+1; $C = floor($year/100); $Y = $year%100-(($m<11)?0:1); $W = ($day + floor(2.6*$m - 0.2) - (2*$C) + $Y + floor($Y/4) + floor($C/4)) % 7; return ($W==5 && $day==13); }
  6. There are many ways to output content in multiple columns, rows, whatever. Your "flexbox" solution is just the presentation for the output. You still need the logic to produce that output. While you have a working solution, I would propose a different approach. Run through the DB results and create a structured array. Then use that array to produce the output in a simpler process. Also, as a side note, I would suggest putting the level descriptions in an associated table and JOIN it in your query rather than hard coding it in the code. I did not test this, so there may be a minor typo or two. But, the logic is sound $query = "SELECT * FROM a_allstars WHERE level > 0 ORDER BY level desc, grad desc,nameLast"; $results = mysqli_query($con,$query); //echo mysqli_error($con); $level = array ( // Figure out what they did after MIBFL 0 => 'D1 Players', 1 => 'Indiana All-stars', 2 => 'Mr. Basketballs' ); //Process the results into structured array $dataAry = array(); while($line = mysqli_fetch_assoc($results)) { $dataAry[$line['level']][$line['grad']] = $line; } //Iterate over each level data foreach($dataAry as $levelId => $levelAry) { //Level header and opening div echo "<div class='header'><h2>{$level[$levelId]} in the MIBFL</h2></div>\n"; echo '<div class="allstar-container">'; // starts flexbox for each change of Level //Iterate over each grade data foreach($levelAry as $grade => $gradeAry) { //Opening Grade div and header echo "<div class='grad-item'>\n"; echo "<div><h3>Class of 20{$grade}</h3></div>\n"; //Iterate over each record foreach($gradeAry as $line) { echo "<div class='player_card'>\n"; echo "<div class='name'><b>{$line['nameFirst']} {$line['nameLast']}</b></div>\n"; echo "<div class='schools'>{$line['schoolHigh']} :: {$line['college']}</div>\n"; echo "</div>\n"; } //Closing grade div echo '</div>'; } //Closing level div echo '</div>'; }
  7. Or I could just use the Print option and print the web page to a PDF file! In this case the decision on "HOW" to store the content is irrelevant from a security concern. Determien the best format based on the best delivery method for the user. Since the intent is not for the user to download for later use, then PDF is probably not the option. But, if I was a user on your site I would think it is pretty stupid that I can't download the content I paid for to read when it is convenient for me (i.e. on a plane for example). But, you just need to decide what makes sense for you. The security is irrelevant because each method can be adequately 'protected' from direct access: Static HTML, Dynamic HTML (from database) or PDF files. It just doesn't matter. If you take this approach the Chapters/sections should just be the raw HTML markup. They should all use a common stylesheet. Here is a very generic example. User goes to a url such as getbook.php?bookid=3&chapter=5 (a chapter/section id is only needed if the book is split up). <?php $bookId = intval($_GET['bookid']); $chapter = intval($_GET['chapter']); if (user has permission to $bookId) { //Define path to the content $bookContent = "/my_secured_directory/{$bookId}/{$_GET['chapter']}.htm"; } else { //Error condition - redirect user to an error page } ?> <html> <head> //Include common stylsheet </head> <body> //HTML that comes before the book output <div id="book_content"> <?php include($bookContent); ?> </div> //HTML that comes before the book output </body> </html>
  8. OK, I'll admit I stopped reading the responses after a while. If your stated goal is to prevent cart abandonment, then don't add unnecessary steps to the process! I say go ahead and let them complete the checkout process with an unconfirmed email address. After they have completed the payment process, display the order confirmation details along with a warning that their email has not been confirmed. It should warn them that until it is verified that being able to look up order status, change orders, whatever may not be possible. That should give them a call to action to verify it. Also, one problem with your plan that I didn't see stated. If a user enters an email address and you have the system send a code, what is to prevent the user from changing the email address in the form before the final submission? >> user then decides they want to use a different email and changes the value before the final submission. So, you can't assume that the email address at the final submission is the same as the one previously provided. You would have to do a check to make sure it wasn't changed and, if so, do another email validation. This is all overly complicated. Plus, you should never re-populate sensitive fields such as passwords and CC numbers. This is a bad approach on many levels as far as I'm concerned.
  9. And what is to stop someone from saving the content displayed in the webpage and sharing that just as they would with a PDF? Heck, the user can just "print" the web page to a file (PDF, HTML, etc.). Anything that is viewed on a webpage can be copied (even if you try to implement some javascript hacks - which you should NOT do). Storing the content in a database does nothing to prevent this type of tampering either. Regardless of whatever method used to deliver your content (PDF or HTML) - it doesn't matter. I think your concern is about people directly accessing the content. That is easy to control - don't put the files in publicly accessible areas! Put them in a directory that is outside of the public folders. Your PHP files when being processed will be able to access the files, but a user could not access them through a URL. After you validate that the user can view a particular resource) just include the file in the output. That will prevent unauthorized access to the content from your web server. But, as stated previously, once you present content to a user, there is really nothing you can do to prevent them from copying/saving the content.
  10. As ginerjm stated we don't have any insight into how the function query_posts() works or what are the valid values to use. query_posts('meta_key=post_views_count&posts_per_page=3&orderby=meta_value_num& order=DESC'); Does that function allow for parameters based on date ranges? Does it exclude records with 0 views? Even if it does, we have no idea how those parameters are to be formatted. But, generally speaking the query might look something like this: SELECT *, COUNT(v.id) as viewCount FROM posts_table as p JOIN views_table as v ON p.id = v.post_id AND v.date >= DATE(NOW()) - INTERVAL 7 DAY ORDER BY viewCount DESC
  11. Unfortunately, there is no perfect answer. Every "spam" system can have different things it looks for to determine what is spam. If there was a simple list of things to do, then every spammer would do those things so their email would not wind up in spam. You will want to do some research, but here a a few things to consider: 1. The server sending the email should be an "authorized" sender for the domain in the from address. In this case you are using Gmail to send an email on behalf of 'bidsoliciationapp.com'. There are ways to change the MX records (similar to DNS records) to authorize a server for a particular domain. But, I think that would require reaction from Google as well if you want to use your current configuration. You may need to use a Google from address or use a dedicated emailing service that can help with the right configuration. Of course, that would cost money. I only understand these things tertiarily, so some of my 'facts' may be slightly off. 2. The name of the domain could be problematic with words such as "bids", "solicitation" could raise a red flag. 3. Content: I would not start with a "Hello Bob, please click <here> . . . " It just seems like something I would see in a Spam email. I don't know if that is part of the problem or not. What you can do: Set up an account with a few different email providers and send some samples of your current emails to them to see if any are flagged as spam. If so, then change the content to something completely innocuous. Does that go through w/o being detected as Spam? If yes, then you know it is the content causing the detection. If not, then it is likely something to do with the configuration/meta data.
  12. Then get rid of all the nested loops! That is what is sucking up all your memory. It would also help if you read the documentation. The documentation for the spreadsheet code you are using mentioins there is a memory problem and how to resolve it. Based on their recommendations, I would follow Barand's earlier advise to put the data into an array first. <?php //Run ONE Query to get the data for ALL the salespeople $sql="SELECT x, y, z . . "; //run the query $result =odbc_exec($connect,$sql); if(!$result){ exit("Error in SQL"); } //Create array to hold the data $salesData = array(); //Iterate through the data and populate a structured array while ($row = odbc_fetch_array($result)) { $salesData[$row['salespersonID']][] = $row; } //Iterate over the structured array to create the spreadsheets foreach($salesData as $salesPersonID => $salesPersonData) { //make a new spreadsheet object $spreadsheetObj = new Spreadsheet(); //Add all the standard setting and content (e.g. headers) //Iterate over the records for the current salesperson and all to the spreadsheet foreach($salesPersonData as $salesData) { //Refernece the records using the $salesData array } //I assume there would be a step here to write the current sheet to disk ########################### ## Disconnect and unset the spreadsheet object ########################### $spreadsheet->disconnectWorksheets(); unset($spreadsheet); }
  13. I am curious as well. Why not just create each spreadsheet when requested by a user. I.e. User selects to see the data for Salesperson X - create the spreadsheet for Salesperson X only at that time. In any event, you have a lot of loops going on with many "expensive" operations being repeated in those loops. For example, you're still running individual queries for each salesperson. Run ONE query to get all the data - THEN create your output for each spreadsheet from that query. You're also recreating the $spreadsheet object for each salesperson. Not sure, but that may not release any memory for the previous object. You shoudl create the object ONCE then create multiple spreadsheets using that object.
  14. I'm not going to bother even reading through your code. You need to STOP, take a breath, and come up with a logical, repeatable process for form validations. Here is an example of the start of a process you could follow: <?php //Create arrays of valid values for fields using a 'list' (e.g. select, radio group, etc.) // - the array index represents the value // - the array value represents the label // This could be created from a DB query if the lookups are stored there. // Use this for BOTH the validation AND for creating the select list, radio group, etc. // FYI: You can't assume the value passed for a select list is one you provided!!! $field4Values = array( 1 => "Blue", 2 => "Green", 3 => "Red", 4 => "Yellow" ); //Create array to hold the errors $errors = array(); //Check if form was submitted // I usually have form pages submit to themselves so I can repopulate fields // if there are errors. So, should only do validations if the form was submitted if($_SERVER['REQUEST_METHOD']=='POST') { //Trim all the post values // You have to determine if this is appropriate (can some legitimate value have // beginning/ending whitespace?). Also, can't use array_map like this if the // post fields contain multi-dimensional arrays array_map('trim', $_POST); //Validate the fields //Field is required if($_POST['field1']$_POST['field1']=='') { $errors['field1'] = "Field 1 is required"; } //Field is NOT required, but must be a number if($_POST['field2']!='' && ) { $errors['field1'] = "Field 2 must be a number"; } //Field IS required, and must be a number if($_POST['field3']=='') { $errors['field3'] = "Field 3 is required"; } elseif(!ctype_digit($_POST['field3'])) { $errors['field3'] = "Field 3 must be a number"; } //Field must contain a values in a predetermined list if(!array_key_exists($errors['field4'], $field4Values)) { $errors['field3'] = "Field 4 is not a valid color"; } // And so on, and so on //Create 'helper' functions for more complicated validations: //Validation process complete - see if there were errors if(empty($errors)) { //Add logic to process the form data - e.g. database insert/update //Redirect to another page: e.g. update successful, listing, etc. //Read up on PRG - (Post, Redirect, Get) for form processing header('http://mydomain.com/formsuccess.php'); exit(); } //If there were errors, code continues to form display logic } //Include the code to display the form //This should display the errors if any exist //and populate any fields with previously POSTed values include('formpage.php'); ?>
  15. You don't mention anything about HOW you want to change it, so there is no way we can provide much guidance. Your script is calling a function "PT_LoadPage". That function takes two parameters. The first appears to be a description of the "type" of output: e.g. a list or content. The second is the array. I would assume those two "types" of output expect an array in the exact configuration as you are passing them now. So, you will need to find the function and modify that. However, if all you want to do is substitute a value in the current array with something else you can either change the process that runs the query to generate the data to create an array with the same structure (but different values) or add some process to change va;lues in the array. But, since you've not provided any description of what/how you want to change the output - I don't know what to say.
  16. Yes, you should combine them - never run queries in loops. I would suggest modifying the names of your fields in those two tables. Both tables have fields called "name" and "message". It is possible to run a JOINed query on those two tables, but you will need to create aliases - otherwise it is ambiguous when trying to reference "name" in the result set. E.g. in the SELECT condition you could do this to add aliases SELECT m.message_ID, m.name as messageName, m.subject, m.message, r.reply_ID, r.name as replyName, r.reply_day, r.message as reply But, why go to the trouble of using aliases when it would make more sense to rename those fields to be unique? Using "message_ID" in both tables makes sense since is a primary/foreign key relationship. Anyway, here is how you could combine those queries. SELECT m.message_ID, m.name as messageName, m.subject, m.message, r.reply_ID, r.name as replyName, r.reply_day, r.message as reply FROM `messages` m JOIN `replies` r ON m.message_ID = r.message_ID ORDER BY `message_ID` ASC, `reply_ID` DESC LIMIT 0,200
  17. Agree. Although I would say there is a case where "protecting a form field" is directly related to "outputting user-supplied data". When populating a form field value (e.g. when editing a record) it would be appropriate to escape the content in the value parameter. Not sure if that is what the OP is asking about since what is being asked doesn't exactly make sense.
  18. I would be interested to know WHY you are wanting to do this. What are these "duplicate" records for and if their data is the same as the 'parent' why do you need to refer to the parent for the data? Also, since each element doesn't have a defined index I'm not sure how you want to make the reference. Do you just want to store the first element value (e.g. '10') in the child element? This would be a lot easier to work with if the elements also had named indexes. Anyway, here is a possible solution. Note, once you run this IF you change one of the referenced values in a parent element it WILL be reflected in the child elements. function mapArrayReferences(&$inputArray) { //Create array to map unique value sets $mappingAry = array(); foreach($inputArray as $elementKey => $element) { //Remove the first element off the array array_shift($element); //Create a hash of the remaining array $hash = md5(implode("|", $element)); //Check if the hash already exists in the mapping array $parentKey = array_search($hash, $mappingAry); if($parentKey !== false) { //Change the current element values to refer to parent $inputArray[$elementKey][1] = &$inputArray[$parentKey][1]; $inputArray[$elementKey][2] = &$inputArray[$parentKey][2]; $inputArray[$elementKey][3] = &$inputArray[$parentKey][3]; $inputArray[$elementKey][4] = &$inputArray[$parentKey][4]; } else { //Add new parent to mapping array $mappingAry[$elementKey] = $hash; } } return; } Usage $dataAry = array( array("10", 25, 31, "Yes", "No"), array("20", 21, 18, "No", "No"), array("30", 11, 47, "No", "No"), array("40", 14, 60, "No", "No"), array("Ten", 25, 31, "Yes", "No"), array("dix", 25, 31, "Yes", "No"), array("twenty", 21, 18, "No", "No") ); //Map child elements to parent element values mapArrayReferences($dataAry); //Change a parent element value $dataAry[0][2] = 99; print_r($dataAry); Output
  19. That is NOT what Barand suggested. You don't create some arbitrary array of salespeople. You use your query results to dynamically create the array BEFORE you start creating your output. You should really break up your functionality into distinct functions/files/etc. It will make things so much easier. Try adding better organization to your code and you know exactly where the problem is based on the error. Anyway, I did my best to rewrite the code using Barand's suggestion and adding a better structure. Obviously I can't test it as I don't have your DB, but hopefully thi swill work or you can fix whatever minor errors I may have introduced <?php //call the autoload require 'vendor/autoload.php'; //load phpspreadsheet class using namespaces use PhpOffice\PhpSpreadsheet\Spreadsheet; //call iofactory instead of xlsx writer use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Fill; ############### Begin styling arrays ############### //table head style $tableHead = [ 'font'=>[ 'color'=>['rgb'=>'FFFFFF'], 'bold'=>true, 'size'=>11 ], 'fill'=>[ 'fillType' => Fill::FILL_SOLID, 'startColor' => [ 'rgb' => '538ED5' ] ] ]; //even row $evenRow = [ 'fill'=>[ 'fillType' => Fill::FILL_SOLID, 'startColor' => [ 'rgb' => 'F2F2F2' ] ] ]; //odd row $oddRow = [ 'fill'=>[ 'fillType' => Fill::FILL_SOLID, 'startColor' => [ 'rgb' => 'FFFFFF' ] ] ]; ############### End styling arrays ############### ############### Begin Data Abstraction ############### // Create DB connection $connect =odbc_connect(removed); if(!$connect) { exit("Connection Failed: " . $connect); } //the sql query $sql="SELECT ARPINVOICEDATE ,ARJSALESEMPLOYEEID ,ARPARINVOICEID ,UARPSALESORDERNUMBER ,ompCreatedDate ,ARPCUSTOMERORGANIZATIONID ,CMONAME ,CMOCUSTOMERGROUPID ,cmoState ,ARLINVOICEQUANTITY ,ARLPARTID ,ARLUNITOFMEASURE ,ARLPARTGROUPID ,ARLFULLEXTENDEDPRICEBASE ,ARLEXTENDEDDISCOUNTBASE ,ARLEXTENDEDPRICEBASE ,ARLSALESORDERID ,case when arlPartGroupID = 'PROMO' then 4.00 when arlPartGroupID = 'DC' then 2.00 when cmocustomergroupid = 'LIST' then 5.00 when cmocustomergroupid = 'VOL' then 4.00 when cmocustomergroupid = 'VOL2' then 4.00 when cmocustomergroupid = 'VOL2' then 5.00 else 5.00 end as comission_percent FROM M1_KF.dbo.ARInvoices INNER JOIN M1_KF.dbo.ARInvoiceLines ON arpARInvoiceID = arlARInvoiceID LEFT OUTER JOIN M1_KF.dbo.organizations ON ARPCUSTOMERORGANIZATIONID = cmoorganizationid LEFT OUTER JOIN M1_KF.dbo.arinvoicesalespeople ON arparinvoiceid = arjarinvoiceid left outer join M1_KF.dbo.SalesOrders on ompSalesOrderID=UARPSALESORDERNUMBER where arlsalesorderid !='' and arpPostedDate >='05-01-2019'and arpPostedDate <'06-01-2019' and arlPartGroupID not in('FRT') ORDER BY ARJSALESEMPLOYEEID,arpARInvoiceID"; //run the query $result =odbc_exec($connect,$sql); if(!$result){ exit("Error in SQL"); } //Process the data into an array $salesData = array(); while ($row = odbc_fetch_array($result)) { //loop through the data $salesData[$row['ARJSALESEMPLOYEEID']][$row['arpARInvoiceID'] = $row; } //Close connection odbc_close($connect); ############### End Data Abstraction ############### ############### Begin Create Spreadsheet ############### //make a new spreadsheet object $spreadsheet = new Spreadsheet(); //get current active sheet (first sheet) //set default font $spreadsheet->getDefaultStyle() ->getFont() ->setName('Arial') ->setSize(10); //Loop through records for each sales data $lastSalesID = false; foreach($salesData as $salesId => $salesData) { //Check if this is a different sales id than the last if($salesId !== $lastSalesID || ) { //If not the first salesID, create a new worksheet if($lastSalesID !== false) { $spreadsheet->createSheet(); } //Set new last sales ID $lastSalesID = $salesId; //Create the worksheet header data //heading $spreadsheet->getActiveSheet()->setCellValue('A1',"Comission"); //merge heading $spreadsheet->getActiveSheet()->mergeCells("A1:P1"); // set font style $spreadsheet->getActiveSheet()->getStyle('A1')->getFont()->setSize(20); // set cell alignment $spreadsheet->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER); //setting column width $spreadsheet->getActiveSheet()->getColumnDimension('A')->setWidth(25); $spreadsheet->getActiveSheet()->getColumnDimension('B')->setWidth(20); $spreadsheet->getActiveSheet()->getColumnDimension('C')->setWidth(20); $spreadsheet->getActiveSheet()->getColumnDimension('D')->setWidth(30); $spreadsheet->getActiveSheet()->getColumnDimension('E')->setWidth(25); $spreadsheet->getActiveSheet()->getColumnDimension('F')->setWidth(25); $spreadsheet->getActiveSheet()->getColumnDimension('G')->setWidth(25); $spreadsheet->getActiveSheet()->getColumnDimension('H')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('I')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('J')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('K')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('L')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('M')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('N')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('O')->setWidth(10); $spreadsheet->getActiveSheet()->getColumnDimension('P')->setWidth(10); //header text//current row $spreadsheet->getActiveSheet() ->setCellValue('A2',"INVOICE DATE") ->setCellValue('B2',"SALESPERSON") ->setCellValue('C2',"INVOICE ID") ->setCellValue('D2',"ORDER ID") ->setCellValue('E2',"ORDER DATE") ->setCellValue('F2',"CUSTOMER ID") ->setCellValue('G2',"NAME") ->setCellValue('H2',"GROUP ID") ->setCellValue('I2',"STATE") ->setCellValue('J2',"QTY") ->setCellValue('K2',"PART") ->setCellValue('L2',"UOM") ->setCellValue('M2',"GROUP") ->setCellValue('N2',"GROSS") ->setCellValue('O2',"DISCOUNT") ->setCellValue('P2',"NET"); //set font style and background color $spreadsheet->getActiveSheet()->getStyle('A2:P2')->applyFromArray($tableHead); //Output invoice records $lastInvID = false; $exrow = 3; //Set starting row for current sheet foreach($salesData as $invId => $invData) { $spreadsheet->getActiveSheet() ->setCellValue('A'.$exrow ,$data['ARPINVOICEDATE']) ->setCellValue('B'.$exrow ,$data['ARJSALESEMPLOYEEID']) ->setCellValue('C'.$exrow ,$data['ARPARINVOICEID']) ->setCellValue('D'.$exrow ,$data['UARPSALESORDERNUMBER']) ->setCellValue('E'.$exrow ,$data['ompCreatedDate']) ->setCellValue('F'.$exrow ,$data['ARPCUSTOMERORGANIZATIONID']) ->setCellValue('G'.$exrow ,$data['CMONAME']) ->setCellValue('H'.$exrow ,$data['CMOCUSTOMERGROUPID']) ->setCellValue('I'.$exrow ,$data['cmoState']) ->setCellValue('J'.$exrow ,$data['ARLINVOICEQUANTITY']) ->setCellValue('K'.$exrow ,$data['ARLPARTID']) ->setCellValue('L'.$exrow ,$data['ARLUNITOFMEASURE']) ->setCellValue('M'.$exrow ,$data['ARLPARTGROUPID']) ->setCellValue('N'.$exrow ,$data['ARLFULLEXTENDEDPRICEBASE']) ->setCellValue('O'.$exrow ,$data['ARLEXTENDEDDISCOUNTBASE']) ->setCellValue('P'.$exrow ,$data['ARLEXTENDEDPRICEBASE']); //set row style $rowStyle = ( $exrow % 2 == 0 ) ? $evenRow : $oddRow; $spreadsheet->getActiveSheet()->getStyle('A'.$exrow.':P'.$exrow)->applyFromArray($rowStyle); //increment row $exrow++; } //Create filter for current sheet //define first row and last row $firstRow=2; $lastRow=$exrow-1; //set the autofilter $spreadsheet->getActiveSheet()->setAutoFilter("A".$firstRow.":P".$lastRow); } } ######## OUTPUT THE FILE ################ //set the header first, so the result will be treated as an xlsx file. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); //make it an attachment so we can define filename header('Content-Disposition: attachment;filename="result.xlsx"'); //create IOFactory object $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); //save into php output $writer->save('php://output');
  20. Also, you need to look into how to make your capturing conditions "greedy" or "non greedy". By default, matches will be greedy. So a condition such as "A(.*)B" with the string "A1B A2B A3B" would find one match "1B A2B A3" - everything form the first "A" to the last "B". If you wanted to find all the values between each set of A/B, then you need make the match non-greedy - "A(.*?)B"
  21. This is not a use case where you should be using RegEx. A better solution is to use a DOM parser such as Simple HTML Dom. You can easily find elements by searching by multiple parameters - such as tag and class. Using the above content you could get every DOM object for every Div with the class "previewSegment" - which would appear to hold all the contents for each title. Then use the DOM parser to get the text within the "previewTitle" div and the "previewLabel" (which is the runtime). That is how you should be doing this. But, it can be done via RegEx, I just wouldn't advise it. $regEx = "#<div class=\".*?previewLabel[^\"]*\">(.*?)</div>.*?<div class=\"previewTitle\">(.*?)</div>#is"; preg_match_all($regEx, $content, $matches, PREG_SET_ORDER); $titles = array(); foreach($matches as $match) { $titles[] = array( 'title' => $match[2], 'duration' => $match[1] ); } echo "<pre>".print_r($titles, 1)."</pre>"; Example output:
  22. Please read requinix's earlier response. If you are still getting the full output with your code above, that is because the function wpjm_the_job_description() is outputting the content to the page and not returning it. E.g. wpjm_the_job_description() { $value = "Get some text from some process or source to be displayed"; echo $value; //The function is directly outputting text to the page return; //Nothing is returned from the function for you to modify it } You will either need to see if there is a function to get the string rather than outputting it or you can try modifying that function directly.
  23. If you want to do this with mysqli, there is a comment in the documentation with an example class: http://www.php.net/manual/en/mysqli-stmt.bind-param.php#109256 But, PDO is the way to go.
  24. To add to benanamen's response, it is not valid HTML markup to have multiple elements with the same id as you have with the checkboxes. The id for each element must be unique. <select id="choose" name="choose"> $vehicles = implode(', ', $_POST['vehicles'] ); $choose = $_POST['choose'];
  25. Someone asked a similar question a long time back and someone pointed them toward the PSR coding standards. So, that's another option: http://www.php-fig.org/psr/psr-2/
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.