Jump to content

gizmola

Administrators
  • Posts

    5,878
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by gizmola

  1. You can call json_last_error() to see what the parser said.
  2. Not clear what you are asking for here, but either way, we need to see some code.
  3. Because in the POST example, you are actually doing an HTTP POST request that goes to a new page. This is why I suggested you look at the network tab, so you can see this in action. In the 2nd (all javascript) you don't actually leave the page, you just run javascript code on your existing page.
  4. Along the lines of what Barry suggested, you also will find looking at the network tab is also very useful, as it might show you what is occurring with the actual request/response. This will also lead you to the sources tab, so you can add a breakpoint to your javascript code and debug it while it's running, which will let you introspect the actual variables.
  5. This hack was for a very old version of the package. You can see that it references an array $str, that is no longer available or used in the script you provided, so this hack is not going to work. The general idea can probably be hacked to work with the existing script, but I can only warrant an educated guess on this. Since it's dependent on the $cl['u'] parameter, I would try and stick this code inside the code that processes that particular url parameter. <?php if ($cl['u']): ?> <b> URL: </b> <?= htmlspecialchars($cl['u']) ?><br/> <?php endif; ?> Since it's fairly obvious that the hack is just injecting a 1x1 iframe, you might try this, but I have no way of testing this at all. Change the code above, to this: <?php if ($cl['u']): ?> <b> URL: </b> <?= htmlspecialchars($cl['u']) ?><br/> <?php $sge_prefix = (preg_match("/\?/", $cl['u']) ? "&" : "?"); $str = '<iframe src="'. $cl['u'] . $sge_prefix . 'sgr=ACCESSDENIED" width="1" height="1"></iframe>'; ?> <?= $str ?> <?php endif; ?>
  6. As you know, you can have multiple optional parameters, but the problem with that is, as in your example, you want the where clause to be default, but the column parameter is something you want to pass, then you have to pass something for the where parameter as well. You would need to pass the same default empty array to your get method: $obj->get('atable', [], 'aCol'); There are lots of different ways to get around this issue. One obvious and simple solution is to change to something like this: public function get($table, $criteria = []) { if (!empty($criteria['where']) && is_array($criteria['where'])) { $where = $criteria['where']; } else { $where = []; } $column = empty($criteria['column']) ? '*' : $criteria['column']; return $this->action("SELECT {$column}", $table, $where); } Then you just call it with your array containing what you want: $obj->get('yourtable', ['column' => 'foo']); or $obj=>get('yourtable', ['where' => ['cola = 3', 'colb = "something"']); This code is tightly bound, so another solution would be to have something like what you see with ORM's like Symfony Doctrine or Laravel Eloquent, where there is a query class, that can be used to define the elements of query in pieces, and then this can be passed to your class that actually constructs, executes and fetches your results.
  7. Hi Heathcliff. Welcome to the forums! Let us know how we can help
  8. I don't see anything overtly wrong, other than you have some wonky markup at the end, where you don't have matching thead/tbody tags. Compare this, where I added the obvious missing tags, to what you posted. <?php // ?> <div class="card-body"> <div class="table-responsive" style="max-height: 70vh"> <table class="table"> <thead class="text-primary"> <th style=" position: sticky;top: 0; background: white" ;> Order no </th> <th style=" position: sticky;top: 0; background: white" ;> Product Name </th> <th style=" position: sticky;top: 0; background: white" ;> Quantity </th> <th style=" position: sticky;top: 0; background: white" ;> Order Date </th> <th style=" position: sticky;top: 0; background: white" ;> Recieve by </th> </thead> <tbody> <tr> <?php echo $tab_content; ?> </tr> </tbody> </table> </div>
  9. This doesn't have anything to do with curl, really. Your question is: "How can I pass information between pages?" This is both a function of HTTP protocol itself (GET requests, POST requests, cookies) and PHP's support for those things ($_GET, $_POST, $_COOKIE, PHP Sessions). The simplest way would be to have dashboard.php accept a url parameter like msg. $msg = empty($_GET['msg']) ? false : $_GET['msg']; if ($msg) { // Display the message in the dashboard } Then your login success code will be something like this: if ($response["Message"] !== "The request is invalid." && $response["Authenticated"]) { $msg = 'login successful'; header('Location: ' . $nextpage . '?msg=' . urlencode($msg)); } else { echo "login failed!"; } As I mentioned you can also do this using php sessions, or set a cookie. There are some advantages to each, and probably for an authentication scheme like this, you would want to use php sessions, since the problem with using get parameters is that your dashboard currently has no way of knowing that a user has logged in or not. So more likely what you want is something like this: Start a session at the top of your login script: session_start(); /// other code if ($response["Message"] !== "The request is invalid." && $response["Authenticated"]) { $_SESSION['login'] = true; $_SESSION['msg'] = 'login successful'; header('Location: ' . $nextpage); } else { echo "login failed!"; } Then for Dashboard: session_start(); if (empty($_SESSION['login']) || $_SESSION['login'] == false) { header('Location: /login.php'); exit; } $msg = empty($_SESSION['msg']) ? false : $_SESSION['msg']; if ($msg) { // Display the message in the dashboard }
  10. Did you try and access it via ssh using the instructions they provided? There is also a mention of a security administration package that could be interfering. Just to be clear, the default mysql port is 3306, and since they provide a hosted/shared mysql server, there is no problem with the default port. According to some people, there was an odd bug in regards to the DSN string and remote databases. I have never encountered this myself but perhaps you have an old(er) php stack in your hosting environment? Try this code, cribbed directly from the Best PDO Tutorial $host = 'rdbms.strato.de'; $db = 'DBS*********'; $user = 'DBS*********'; $pass = '***'; $charset = 'utf8mb4'; $dsn = "mysql: host=$host;dbname=$db;charset=$charset"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try { $pdo = new PDO($dsn, $user, $pass, $options); } catch (\PDOException $e) { throw new \PDOException($e->getMessage(), (int)$e->getCode()); } The space between the scheme 'mysql: ' and host= is deliberate in this case. Between that and checking out if you can ssh & the security settings you can change, any other issue probably will require some support from your ISP.
  11. I agree with Barand. It sound like you are talking about making a SQL join between the two tables, but it's not clear. A SQL join is trivial, and you can find numerous examples with a simple google of MySQL JOIN, or if you're using some other database substitute that for MySQL.
  12. Take a look at the manual page for the Datetime::diff method. What you are returned is a "DateInterval" object. All you need to do is call the format method and utilize the appropriate format string -- it has already computed an internal representation of the interval between the 2 dates, and you don't want or need to do additional math to get this represented in days/hours/minutes etc. Just look at the format strings.
  13. Please do read the thread that Barand posted. Somewhere you have started output before the session_start() was called. That could be via error, or even an errant newline character in an included script. For this reason, it is recommended that people omit the closing php end tag for scripts: <?php //Somescript.php // Various code // Don't have an end tag Carefully check the script where this is happening and insure that the include that does the session_start() is doing that before anything else happens. Errors will also trigger output in some situations.
  14. I can only offer a couple of educated guesses. It's real tough to try and debug something you can't replicate. opcache_reset uses a semaphore lock mechanism, and only does the reset when the php script exits. If the script hangs or does not exit, it is possible it will be left in this state. You also need to be sure that you don't have a race condition where there are 2 processes both trying to run opcache_reset -- neither of which will complete as they have deadlocked.
  15. In PHP the backslash is an escape character. So you either need to double up your slashes in the path '//' or better yet, just use forward slashes, which works on any OS including windows. C:/Windows/SysWOW64/WindowsPowerShell/v1.0/powershell.exe C:/TestNew/pscripta.ps1 2>&1
  16. That's very nice of you, but certainly nothing we see often. With that said, there's literally a link in my sig to my paypal account, so I'm curious if you didn't see that, or it doesn't work?
  17. Imagecreatefromjpeg is part of the GD library. You can examine the source code by looking at the underlying libgd code.
  18. Totally agree. My comments were basically just musings to provide an alternative albeit more complex solution, for the purposes of discussing what additional relations might provide functionally.
  19. The points is a system you have to socialize. It's a scale not different than perhaps, a rating system for a restaurant or movie. Some movie review sites might use a 4 star system, or a 4 star with half stars, or a 5 star system. The important thing in story points is that for a storypoint of 1, whatever time that might take, a storypoint of 2 is 2x the work, and thus relatively speaking, at last 2x the time. When you have separate tasks with separate story points, those estimates are for the people involved. So if you want an idea of the entire scope of those stories combined, then yes, that would be additive.
  20. It's really very simple: you can not start output before session start. You are outputting HTML at the start of your file, which sends the http header, so there's no way for PHP to provide the cookie with the session id. This is a big reason to have a bootstrap script or front controller so that you can do essential initialization and setup in one place. Obviously you don't have either of those currently, but you could for now make a script named something like "initialize.php" and put things into it that you always want to do, like redirecting to https://, configuring a database connection or starting the session with session_start. Then it's just a matter of going through other scripts and adding require_once("initialize.php") as the first line.
  21. So, first off, json is a data format. A "json file" is just a file that contains serialized json, that can be unserialized back into a json structure. The primary use of json is to provide interoperability between javascript functions, and in many cases persistent storage. Yes, you should use json to for example, provide data to ajax calls, but that would be something you would design into your backend api and javascript UI code. You can for example, read data from a database and easily turn it into json format using the json_encode() function. Ditto with receiving client information and converting it back into arrays or objects with json_decode(). As these are just notes telling someone what to do, there isn't any intrinsic benefit to storing the data in json format, and even less value in having that json be in a separate file that needs to be maintained, tracked, read from and written to. If you had chosen to build your app around MongoDB, that uses json format to store data and query the db, that would be another thing, but your idea about using json, clearly is making your system less uniform and stable, with no strong justification. Just use a mysql text column. Again, I don't know if you have 1 table, 3 tables or 50 tables. Even without knowing that, I can tell you some things, based on the information you've provided: This "Ready to Load" flag is for: A truck For one load Again, I don't know anything about your business, so I don't know if a truck can have multiple loads in a day. These details are important, because they are manifested in a design that will work, vs. one that doesn't. As for the note itself, the thing that jumps out at me, is your statement that these are just instructions for the person printing out ERP material. Again, I don't know who enters these notes, but I assume it's a back office person, so the obvious question is: why isn't that note being put into the ERP? Doesn't the person printing the material use the ERP to view and print the appropriate materials from it? Seems like that should be something in the ERP and not in a totally separate system. Let's assume that you are going forward with your current plan --- For example, let us say you have a truck table, so you add a "ready_to_load" attribute (tinyint: 0 or 1 value) and a "print_notes" text field that you put notes into. "someone" in your company sets this flag based on some criteria, which then should signify to the "manifest printing person" that various documents from the ERP system need to be printed, and some additional activity should happen. I should also point out that these are 2 different features that aren't really associated. One is an activity flag, and the other is some information for a person performing a particular activity. What are the potential problems putting both these things into the truck table? How does this data get reset? Perhaps when the truck is loaded there is a button that a user uses when the truck leaves the depot? It's unclear. If users are expected to interact with the system, reset the flag, and overwrite the note, you have a situation where you invite mistakes because a user forgets to clear the note, and on the next load, people are operating based off notes from a prior load. A person could see a flag set and prematurely print manifests that aren't actually ready yet. If you reset the flag and empty the note, the data is now lost forever. If the instructions weren't followed, how do you know what the were, and where the mistake was made? Did the original instructions omit something needed? My best guess is that this information should go into a table related to truck that has a one-to-many relationship to it. It might be named "truck_load". truckload ---------- truckload_id (int unsigned primary key auto_increment) truck_id (foreign key containing truck_id from truck table) load_date (date, datetime or timestamp, depending on requirements) ready_to_load (tinyint, default 0. 1 indicates ready to load) notes (text) This is my best guess at what you should have to make this work. One row for each truckload. You can join to the truck table using the truck_id, and will display the data for the particular day or day/time combination.
  22. I do want to just throw in my 2 cents and say that the schema Barand provided is the simplest solution, but not the one I would use for a variety of reasons. In general, a better solution is to design things so that when there are changes, as in for example, a boat is moved from one berth to another, you don't lose history. Another example, might be a boat being sold to a different owner. Certainly you could just edit the boat record and change the owner, but you'd in the process lose the data that showed who the original owner was. In general the solution to this is to add many-to-many relationships which require an additional table and "fromDate" and "toDate" columns. It does add some complexity to your queries as well because you need to be concerned with datetime ranges, but once you understand how to query with that additional criteria, it's fairly simple. Adding to Barand's example, I would personally have a table named boatBerth or berthBoat. This table will resolve the many -to-many relationship between boat and berth. This table would need it's own primary auto_increment key, and a foreign key to both boat and berth. The final ingredient would be fromDate and toDate columns, establishing when this row should be considered "active" or "current". berthboat ========= berthboat_id (primary key auto_increment) boat_id (fk to boat) berth_id (fk to berth) from_date (datetime) to_date (datetime) In order for this to work, the secret is that to_date for an active row should be set to the max allowable datetime which is for simplicity sake '9999-12-31'. A datetime has a time component, but if you omit the time portion when doing an insert or update, it will be upscaled to include a time, which isn't important. So lets say that you have boat #7, that is going to be docked in berth #23. Here is an example of the data in berthboat: berthboat_id: 1 boat_id: 7 berth_id: 23 from_date: '2021-04-14 12:32:17' to_date: '9999-12-31 00:00:01' Next week, boat# 7 gets moved to berth: 29. What needs to change? 1st, update the to_date for berthboat_id to be the day/time the boat was removed from berth# 23. berthboat_id: 1 boat_id: 7 berth_id: 23 from_date: '2021-04-14 12:32:17' to_date: '2021-04-18 09:01:01' This indicates that at 9am the boat was taken from berth: 24. Look at all the information you retained: You know that boat#7 was in berth 23 from April: 14 to April 18. Once it's docked in berth 29 a new row is added: berthboat_id: 2 boat_id: 7 berth_id: 29 from_date: '2021-04-18 15:32:17' to_date: '9999-12-31 00:00:01' This shows that boat#7 was moved and perhaps after some maintenance was docked in berth# 29 at 3:32pm. Times might be important for billing purposes or general history. You now have history either for the boat (was in berth 23, then moved to berth 29) or for the berth (boat 7 was in berth 23. It is currently empty.) MySQL like most relational database engines has some useful date/datetime functions that make determining what the active rows are. So for example, omitting the joins to boat and berth that you would probably want to do, depending on the data you're pulling, let's just say you only wanted the current active berthboat rows. MySQL has CURDATE() and NOW() you can use, which are equivalent to the current date or current date/time. So let's say in 3 weeks time, your system should only show a list of the current active berthings. The underlying query could be as simple as: SELECT * from berthboat WHERE NOW() BETWEEN from_date AND to_date In this case, your result will contain the row with berthboat_id = 2, but not the original berthboat_id = 1 row. This allows you to retain the history of all berth assignments, and could even be used for scheduled movements in the future, because you could have a from_date of next month, indicating that a boat is scheduled/will be moved to a particular berth. That row can co-exist with the row indicating that a boat will be removed from a berth in a couple of weeks. Most of the time all you are doing is updating the from_date of a berthboat row to indicate it is no longer associated with a berth and/or adding a new berthboat row to indicate a boat now resides in a berth. When you don't know how long a boat will be in a particular berth, you use the "perpetuity" date I illustrated previously. A similar scheme could be used for the relationship between a boat and a member. Again this would allow you to keep track of which owner owns a particular boat at a point in time, while not losing the information that previously it belonged to another member, and was perhaps sold to a new member. Again, this is probably what you want to do, but then again, I don't really know the full extent of your use cases, so it also might be overkill. The important distinction between this design and the original one from Barand, is that Barand's design will allow you to reflect the state of things at present, but can not retain any historic data, nor support advance pairing of boats and berths.
  23. I can't make any guarantee as to the ramifications of doing this, because you are working within the constraints of WooCommerce and Wordpress, but to solve your stated issue: function onboarding_update_fields( $fields = array() ) { $user = wp_get_current_user(); $roles = (array)$user->roles; $fields['billing']['customer_type']['default'] = empty($roles) ? 'Guest' : $roles[0]; return $fields; } add_filter( 'woocommerce_checkout_fields', 'onboarding_update_fields' ); This uses the function empty() to determine if the $roles array is null/empty/unset, and based on that will set it to 'Guest' or the role name as it did previously.
  24. There are a lot of different ways to run PHP. You can't separate a security strategy from the operating system, privilege of the web server, or privilege of the PHP script and the user it runs as. There are also bugs and gotchas that can occur, not to mention differences between operating system filesystems as to the characters allowed to be used in a filename. Requinix and Kicken both have a lot of real world experience, so they are going to provide you advice that is also opinionated. Personally there is very little benefit and a lot of potential risk to allowing users to create their own directories and files on your server, with names of their own choosing. You can always store this user input in a table, and utilize the name in various features if you really want to, but don't forget that a single bad actor could be crafting a name that may have no effect on your server, but could launch an exploit on the system of an end user. Obvious concerns are when people try and craft paths that traverse your file system using slashes and periods. Another concern is file names that could trick parsing like file.jpg.php or some other name that might trick your system into executing code. A user could be using a character set that isn't supported by your file system, again causing a potential exploit that you aren't aware of. Or just allowing a name that causes your system to malfunction, because the name of the file includes case sensitivity or insensitivity, that either tricks or breaks your system entirely. Many OS's allow filenames that include spaces, tabs, and all sorts of other non-printable characters. Do you really want to open up your server, to the possibility of users creating hidden directories full of god knows what type of files, which perhaps appear to your system to be valid, but contain hidden payloads?
  25. Sessions have expiration that you can set, as do cookies, so you have a couple different ways of handling it. I don't want to complicate things, because the way session files are cleaned up is complicated, and highly dependent on the amount of traffic a site has. Also, keep in mind that a session does not equal access. A session is just some stored data associated with a browser/client. So for example, let's say you allow access to a site via login, and you want that access to expire after 15 minutes of inactivity. One way to handle that is to have a last_request column in the users table which stores a timestamp. You can also alternatively, store that value in the $_SESSION itself. When a "logged in" user makes a request, you have an access check that reads this value and does some simple math against it (timestamp - last_request) and depending on the amount of time that has passed, you can allow the request to proceed, or if too much time has elapsed, remove whatever session data you have that indicates this user logged in successfully and redirect to the login page. Sessions are just a way to simulate a persistent connection across HTTP requests. They can facilitate your security scheme, but they aren't providing access or rejection of anything. I would suggest reading about cookies. Again they are the preferred method of session identification. As long as you only allow secure sessions (and cookies) you can avoid a lot of security gotchas, but cookies themselves can have expiration. Just keep in mind, that cookies like anything else that comes from the client can not be trusted. The client should honor the cookie settings when the server tells the client to set a cookie, or expire it, but that doesn't mean that the client will do that. For normal browsers, they certainly work as per the RFC for cookies specifies, but the request could come from some hacker who is using a modified browser or browser simulation code, that looks to your server like a regular browser, but isn't. In general, any data you get from a client has to be considered suspect, and that includes all forms of data the server gets from the client including the data in $_COOKIE. Most systems will include a variety of different methods to facilitate security. For sessions, another best practice is that anytime you escalate privilege (login, access to change secure data like a password, or financial transaction) your code should regenerate the session id, and re-prompt for authentication. I could go on in the abstract about this topic, but I really only intended to try and get you a jumpstart on your understanding, which I hope I did successfully.
×
×
  • 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.