Jump to content

kicken

Gurus
  • Posts

    4,705
  • Joined

  • Last visited

  • Days Won

    179

Everything posted by kicken

  1. If your using systemd, you may need to configure the ulimit equivalent there, LimitCORE = infinity. Create /etc/systemd/system/php7.3-fpm.service.d/coredump.conf (may need to adjust directory name if your service name is not php7.3-fpm) with the content: [Service] LimitCORE = infinity Reload the configuration with /bin/systemctl daemon-reload then restart the FPM service.
  2. I usually use it when dealing with mysql databases, but that's not very often. I'm not sure what you're expecting to do from it. It's fairly easy to setup and get connected to a DB so you can run queries and look through your tables and data. It has some design tools to help plan and diagram your database and the relationships between tables which take a little more effort to learn, but that's only if you want to use them. I haven't used phpMyAdmin in a long time so I'm not sure I could really compare the two, but I personally prefer having the separate desktop application like Workbench over a web app like phpMyAdmin. To use Workbench you need to be able to connect to the database server directly or via an SSH tunnel. On shared hosting that may or may not be possible, which is why many of them provide something like phpMyAdmin. For your own private server it shouldn't be a problem.
  3. Did you check the ulimit setting? If your script is something you just run from the CLI you don't really need a core dump though, just run it using gdb. kicken@web1:~$ gdb /usr/bin/php7.3 GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git [...] Reading symbols from /usr/bin/php7.3...(no debugging symbols found)...done. (gdb) run yourScript.php Starting program: /usr/bin/php7.3 yourScript.php
  4. You're seeing those characters because the data is UTF-8 encoded (which is generally a good thing) but whatever tool your using is not interpreting it as UTF-8. If you really want to convert it, then maybe try mb_convert_encoding, however the better thing to do is fix (or replace) your tool with one that understands UTF-8 and shows the data properly.
  5. Ok foreach ( $dept_codes as $d ) { $production_history[$d] = []; } This can be replaced with array_fill_keys $production_history = array_fill_keys($dept_codes, []); Next up, foreach ( $dept_codes as $d ) { //loop through returned db rows foreach ( get_production_history( $order_id, $pdo ) as $row ) { if( $row['dept_code'] == $d ) { This ends up querying your database count($dept_codes) times when you only really need to do so once as far as I can tell. For each $dept_codes loop you're querying the database for all your results, then just filtering them out to only the ones matching the current department. Instead of doing that, just query your database once and process the results according to the department in the current row. foreach (get_production_history($order_id, $pdo) as $row){ $d = $row['dept_code']; //set start time if ( !in_array ( $row[ 'id' ], $production_history[ $d ]) && $row[ 'status_id' ] === 1 ) { $production_history[$d][ $row['id'] ] = array( 'submit_time' => $row[ 'submit_time' ], 'finish_time' => '', ); //record id $last_recorded = $row['id']; //set finished time } elseif ( $row[ 'status_id' ] === 3 ) { $production_history[$d][ $last_recorded ]['finish_time'] = $row[ 'submit_time' ]; } } Since your thread was prompted by anonymous functions, why not use them? //find records without a finish time and unset them foreach ( $production_history as $dept => $value ) foreach ($value as $k => $v) if (empty($v['finish_time'])) unset($production_history[$dept][$k]); //find departments without records and unset them foreach ( $production_history as $dept => $value ) if (empty($value)) unset($production_history[$dept]); Could be replaced with a mix of array_filter and array_walk: array_walk($production_history, function(&$entryList){ $entryList = array_filter($entryList, function($value){ return !empty($value['finish_time']); }); }); $production_history = array_filter($production_history); First array_walk loops over the $production_history array like your foreach loop, each value is passed to the function as $entryList (using a reference so we can modify it). Then the function uses array_filter to keep only entries which have a finish_time defined. //if on first entry for dept print parent if ( $dept_arr_count == 0 ) { //generate parent JSON entry $json[] = array( 'pID' => $dept, 'pName' => get_dept_name( $dept, $pdo ), 'pStart' => '', 'pEnd' => '', 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 2, 'pParent' => 0, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); } The if statement check here is unnecessary the way your data is setup. $production_history is a unique array of departments. As such, this part of the loop will only run once per department and there's no need to try and track if you're on a new department. $submit_time = (isset($production_history[$dept][$k]['submit_time'])) ? $production_history[$dept][$k]['submit_time'] : ''; $finish_time = (isset($production_history[$dept][$k]['finish_time'])) ? $production_history[$dept][$k]['finish_time'] : ''; $k is meaningless here. It's value is going to be whatever the last entry of the //find records without a finish time and unset them loop is (or undefined in my replacement version) You're not using these variables anywhere anyway so the entire lines could be removed. I'm not sure what you were attempting with these lines. $dept .''. $dept_arr_count+1 You might have an operator precedence issue here, it's unclear what your goal is. Concatenation and addition have the same precedence and are processed left to right so that expression is ($dept.$dept_arr_count)+1. You combine $dept and $dept_arr_count into a single number, then add one to it. Your spacing however, to me, suggests you intend to add one to $dept_arr_count first, then combine the two numbers. Achieving that requires a set of parenthesis. $dept . ($dept_arr_count+1) In either case, the empty string is unnecessary and can be removed. $production_history[$dept][$k]['submit_time'] $production_history[$dept][$k]['finish_time'] $production_history[$dept][$k] is the same as $v, so you can just use $v['submit_time'] and $v['finish_time'] instead. So, with all those suggestions applied, the new code would look something like this, assuming I didn't goof up somewhere: //fetch production history data if( isset ( $action ) && $action == 'get_production_history' ) { $order_id = $_GET['order_id']; $production_history = []; $last_recorded = 0; $dept_codes = [5,6,7,8,10,11,12]; $production_history = array_fill_keys($dept_codes, []); //loop through returned db rows foreach (get_production_history($order_id, $pdo) as $row){ $d = $row['dept_code']; //set start time if ( !in_array ( $row[ 'id' ], $production_history[ $d ]) && $row[ 'status_id' ] === 1 ) { $production_history[$d][ $row['id'] ] = array( 'submit_time' => $row[ 'submit_time' ], 'finish_time' => '', ); //record id $last_recorded = $row['id']; //set finished time } elseif ( $row[ 'status_id' ] === 3 ) { $production_history[$d][ $last_recorded ]['finish_time'] = $row[ 'submit_time' ]; } } array_walk($production_history, function(&$entryList){ $entryList = array_filter($entryList, function($value){ return !empty($value['finish_time']); }); }); $production_history = array_filter($production_history); $json = []; foreach ( $production_history as $dept => $value ) { //generate parent JSON entry $json[] = array( 'pID' => $dept, 'pName' => get_dept_name( $dept, $pdo ), 'pStart' => '', 'pEnd' => '', 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 2, 'pParent' => 0, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); //print children $dept_arr_count = 0; foreach ($value as $k => $v) { $json[] = array( 'pID' => $dept .''. $dept_arr_count+1, 'pName' => '', 'pStart' => $v['submit_time'], 'pEnd' => $v['finish_time'], 'pClass' => 'ggroupblack', 'pLink' => '', 'pMile' => 0, 'pGroup' => 0, 'pParent' => $dept, //need to set this for those that are children 'pOpen' => 1, 'pDepend' => '', 'pCaption' => '', 'pNotes' => '', ); $dept_arr_count++; } } header('Content-type: text/javascript'); print(json_encode($json, JSON_PRETTY_PRINT)); }
  6. You won't be able to get determine their shift at any given moment by checking the current time. There's not enough information to do that. If it's a system the login to and stay logged into through out the day then you could determine it at login and store it in a session variable. So long as they stay logged in that'd be fine. Even that however could fail if they end up logging out but then have to login again after their shift technically ended for some last minute stuff before going home. So the only ideal solutions are to either Let your users select the shift when making their entries. Perhaps have a supervisor review the entries for accuracy Have a defined schedule you can use to look up their shift. This is less of a technical problem and more of a business process problem. First, determine how their shift is determined in the business process. Many places just use a clock-in/clock-out process where at the start of their shift the employee completes a clock-in process and at the end they complete a clock-out process.
  7. You mis-understand what I mean. Yes it sends the modified request, but that won't cause the currently displayed page to change (if you edit and re-send the document request) or trigger any javascript handlers related to the original request (if you edit and re-send an XHR request). Using that check for notifications request as an example again, if I edit and resend that request, it won't re-show the little popup saying there is a new notification. Likewise with my school example, edit and re-send wouldn't trigger the code that handles a successful login. That's why I had to use breakpoints to modify the original request rather than just edit and resend it.
  8. Because those are the name/value pairs for the form. Every form is going to have something different there. The one in my image is from a XHR request that this site uses to check for new replies to a thread. Yes. That example doesn't need break points, it's a simple form where you'd just modify the DOM with the inspector tool like you mentioned above. Find the <input> tag you want to change and modify it's value attribute. The school's website used a JS library to scan a QR code using a webcam and took then made an XHR request with the data to perform the login. That type of situation is where you need to use break points and it's done via the Debugger tab in the XHR Breakpoints panel. Click the + to add one and enter some URL text to stop on. You probably saw it in the Cookies panel. Like everything else, there's nothing to stop someone from modifying that value to whatever they want. Like the product ID though, it doesn't matter much if they do. Most likely whatever they change it to would be invalid and just result in them starting a new session. If they did happen to change it to another valid session ID then they'd inherit that session. This is why session IDs need to be long, random and should not shared.
  9. The connection will get closed eventually sure, but why leave it laying around unused until then? Close it when your done with it.
  10. Click on the request and it will open all the details in a side panel. One of the tabs of that panel is Params that shows the data that was submitted. There's lots of other info in the other panels that may be useful too. That depends a bit on how things are setup and what you want to do. Firefox has an Edit and Resend button you can use to craft a new request. This just sends the request and shows the response in the dev tools, it won't cause the page to change or trigger and result processing in javascript. If the form is a standard HTML form, just inspect it in the dom and modify the values then submit it. In the case of the schools site, the request was done via XHR so I set a break point on XHR requests (Debugger -> XHR Breakpoints) to find where the request originated from, then set another break point before the XHR request so I could modify the variables used to generate the request. No where in particular. It's just something you learn to do after being a web developer for years.
  11. If you go to the network tab of the dev tools and look at the requests it will show you exactly what was submitted by the form. Nothing on the client side of things is safe from tampering. I used all these tools/techniques a couple weeks ago to "hack" my way into my nieces school platform as their javascript QR code reader wasn't working and that's the only way she had to log in. I submitted a few bad login attempts with the dev tools open to see how they were submitting the data. After that I scanned her QR code with my phone to get the data then used the dev tools to change the data prior to submission so it was correct and get her logged in.
  12. The problem is that you are trying to print_r the result. The object created by that library is large and recursive so you can't just easily dump it.
  13. Add it to your join's ON clause, not the WHERE clause.
  14. It's a little more complicated to setup, but I personally prefer using something like pdf-puppeteer. It essentially spins up a browser to render the page then generate the PDF so you can use most all your modern CSS/HTML (with some limitations) to design the page. I've used it in a few projects and can generally just render the same HTML/CSS as I normally use but without the header/footer and a extra 'pdf' class on the <html> tag. You just have to have node available on the server, create a little javascript program to accept your HTML and generate the PDF then use exec to run it. If you have dedicated hosting or a VPS then it should be relatively simple to setup. If your on shared hosting you'll likely have to ask your host if they support such a thing.
  15. Can you not just check which user logged in and what day it is then check the schedule for their shift? If you just try and check a persons shift when the log in and they may login many times than that won't really work by itself. You need to either have a defined schedule or some sort of clock in/clock out feature to that they use at the start and end of their shift.
  16. Make it so you can submit your form data to a script. Read your form data in the script using $_GET or $_POST depending on your form method. Create your query string from the form data. Concatenate the query string to your base URL. Issue your redirect to the new location.
  17. date_default_timezone_set Setup the timezone to the one you want. For example: date_default_timezone_set('America/Los_Angeles') Then just use your date functions normally.
  18. Looks to me like this is just another bingo thread.
  19. I tend to just stick to using jQuery form for consistency. If I'm already loading jQuery on the page then I'm not going to do something like document.getElementById('blah'), I'll just do $('#blah')[0]. There's a little extra overhead using the jQuery syntax, but the code consistency is more important IMO and it's also shorter to type. That said, for simple things like accessing the value/name of an element in a callback or target of an event I will sometimes just access the property directly rather than using jQuery. For example if making a simple popup handler, I'd likely just do: $('a.popup').click(function(e){ e.preventDefault(); window.open(e.target.href); }); If I want to use jQuery for any reason though in said callback though, then I'll just use it consistently. For example if I wanted to add a data-options attribute for window options, I would use jQuery for that and as a result also for the href. $('a.popup').click(function(e){ e.preventDefault(); var $target = $(e.target); var options = $target.data('options') || ''; window.open($target.prop('href'), 'popup', options); });
  20. All of your if statements are outside of your for loop, meaning they will only run once after your loop completes. I think maybe you want them inside the for loop. Making that change makes the result for 200 match what you posted. Adding a clause to only run the first calculation when x is less than 200 fixes the 201 result. Also, the way your if statements are structured if $x is say 650 you will run each of the formula up to that, ie: $a += $x * round($x + 7 * pow(4, ($x / 290))); $a += $x * round($x + 11 * pow(4, ($x / 280))); $a += $x * round($x + 19 * pow(4, ($x / 270))); When I am guessing you only want to run the last one. If that is correct, then you want to change your if statements to be a chain of if..elseif..else statements that check the ranges using < rather than >, ie if ($x < 200){ ... } else if ($x < 400){ ... } else if ($x < 600){ ... } ...
  21. I setup a Linux VM and tried this as it should be possible. It seems, at least with Linux MX but probably similar on other distros, that a user needs to be in the audio group in order to access the audio devices. Using the second and third parameters to exec, you can get the output of the command and that is where I started at. The -q flag suppresses the progress bar and the 2>&1 redirects the error output to standard out so it can be captured into $output. exec('/usr/bin/play -q notification.wav 2>&1', $output, $ret); var_dump($output, $ret); This produces the output array(11) { [0]=> string(48) "Home directory not accessible: Permission denied" [1]=> string(48) "Home directory not accessible: Permission denied" [2]=> string(57) "ALSA lib confmisc.c:767:(parse_card) cannot find card '0'" [3]=> string(115) "ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_card_driver returned error: No such file or directory" [4]=> string(66) "ALSA lib confmisc.c:392:(snd_func_concat) error evaluating strings" [5]=> string(110) "ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_concat returned error: No such file or directory" [6]=> string(63) "ALSA lib confmisc.c:1246:(snd_func_refer) error evaluating name" [7]=> string(109) "ALSA lib conf.c:4568:(_snd_config_evaluate) function snd_func_refer returned error: No such file or directory" [8]=> string(82) "ALSA lib conf.c:5047:(snd_config_expand) Evaluate error: No such file or directory" [9]=> string(63) "ALSA lib pcm.c:2565:(snd_pcm_open_noupdate) Unknown PCM default" [10]=> string(24) "Floating point exception" } int(136) With the default PHP-FPM setup the PHP script runs as user www-data. The first two errors about the home directory are due to that user's home directory (/var/www) not being writable by the user. I fixed this by changing ownership of /var/www to www-data with chown -R www-data:www-data /var/www The remaining errors are due to the sound devices (in /dev/snd/) being limited in access to users in the audio group. This I fixed by adding the audio group to the list of groups www-data belongs to using usermod -G audio www-data After those changes and restarting Apache and PHP-FPM I was able to hear the sound when loading my test script.
  22. Does /usr/bin/play exist? If not you need to install it first. You need to find some program that will allow you to play media from the command line. Just test things out via a terminal or ssh session until you get it working that way, then take whatever command you come up with and put that into your PHP page with exec(). This is all assuming the computer running apache and the one you want the sound played on are the same. If they are not you will need another solution.
  23. Nope, not a valid assumption. From privacy.com: Using their service it sounds like you can just enter whatever billing info you want. Doesn't have to be your real info. Now what about the corporate/non-profit group that wants all their employees to have an account and pays for them using a single corporate credit card? Uh oh, they can't, or you have to up your limit again to however many employees they have. Yes, having a bunch of accounts for a single card may be fishy and worth attention, but outright trying to deny it isn't really the best solution. You add that fact as an input into your filtering system. That combined with other data can then determine if an account might be trouble and then take action such as flag the account for manual review and/or shadow ban it Yes, because it's a silly restriction that doesn't effectively solve the problem. It'll cause issues for legitimate customers and only be a very minor inconvenience for the real trouble makers. For example you just side-stepped the whole stolen credit cards issue. Even your relaxed name/zip code hash won't solve that because each card will have different details.
  24. Doctrine does it's queries in a more or less fixed sequence that is designed around entity relationships and foreign keys. See this old bug report (UnitOfWork commit order problem) and the code for information. That doesn't always play well with other unique constraints, as you discovered in your list ordering problem. As mentioned in that thread though, there's something to be said for over-using unique constraints, make sure you really need one. For situations doctrine doesn't handle well then the work around is usually to use force queries to run in a particular order by using EntityManager::flush() frequently. I don't use pgsql so I'm not familiar with the deferred constraints but if they seem to provide a solution then it may be worth exploring. However I'd first look at the code and see if there is a solution there through a different design or just removing the constraint.
  25. Not gonna like, this was TL;DR after a few posts and sounds just like previous threads where we tell you something is a bad idea/wont work and you just push back. However, I'll reply anyway. None of those places try to turn a credit card into an identity like you are trying to do. They use the card for what it is, a payment method. Any place that is actually interested in a persons identity will require a government issued ID. Your asking for a persons billing details. Whether you store that or not isn't that relevant, just asking for it will deter a ton of people from even considering signing up for your site. That is simply too much personal info. Now if you want to require payment and think your content is good enough people will pay for it then fine. Don't think that because your not storing that payment data that people won't care that your asking for it. They will, and many will consider it a deal breaker. Storing the name and last 4 in plain text would be fine by PCI standards as far as I understand, no need to even hash it. And here's the crux of why your idea is DOA and not worth even doing. How does it stop what you just said you want to stop? If they are coming back with new card numbers then what good is comparing the old one going to do? This is all you need. The sheer fact that you require payment is deterrent enough. Your average troll isn't going to spend money over and over again to keep posting. Even if they do, then so what? Take that extra money you earn and use it to develop a solution that actually works like paid moderators, better content filtering, etc. You need to consider the real world, not your little fantasy world where people will just re-used the same card, get denied and say "Well darn, they got me!" Most trouble makers will simply be stopped by the fact they have to pay. Once you ban them they will be gone and not try to come back. The trouble makers who are not bothered by the payment will have no trouble defeating your little card check. Most likely they won't care because it won't be their money, they will be using a list of stolen credit cards and they will just move on to the next card in the list. For those who actually are using their own money, they will just sign up for some virtual card number service (if they don't already have one) So the end result is that the only people you'll stop are those who genuinely want to join your community and want to help their friends/family join also by offering to pay their subscription cost for them. They won't be able to due to your stupid little check for duplicate cards. Maybe they will be smart/motivated enough to get a virtual card number and work around the problem, but most likely they will just get turned off to the whole idea and at best, won't buy a sub for their friend or at worst will cancel their sub and stop using the site all together. So how do you accomplish your utopia that you want to create? Require a payment to join that's low enough to not deter a sign up, but high enough to deter repeated signups. Higher people (or convince your community) to moderate the site and take down and ban spam/troll accounts quickly. Invest in technology that helps with #2 like easy to use tools and advanced (AI driven?) filtering to catch problem accounts early/quickly Nothing will be perfect, but your current plan isn't even viable.
×
×
  • 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.