Jump to content

gizmola

Administrators
  • Posts

    6,060
  • Joined

  • Last visited

  • Days Won

    153

Everything posted by gizmola

  1. I looked at your code, but I don't see a problem. What are the full contents of redirect.php? Is it possible you are including the wrong redirect.php? There could also be some sort of syntax issue. I'm not sure what is going on. Are you possibly using Opcache? There are times that Opcache gets a file stuck in cache, and it doesn't read changes. If you are using opcache, you should either turn it off for development purposes, or learn how to clear the cache. I've seen that cause major confusion plenty of times, where people had code that should work, but doesn't and they can't figure out why. This has nothing to do with your problem but since I looked at your code, I figured I'd refactor it for you. function loginSuccess($username, $password) { global $cn; $sql = "SELECT COUNT(*) as countOf FROM admin WHERE username=:username AND password=:password"; $stmt = $cn->prepare($sql); $stmt->bindValue(":username", $username); $stmt->bindValue(":password", $password); $stmt->execute(); $countOf = $stmt->fetchColumn(); return ($countOf > 0); } I fixed your spelling. The word is spelled "success". Use PHP community standards for naming your functions, methods and variables. The standard is to use camelcase. See https://www.php-fig.org/psr/psr-12/ for this and more standards you should conform your code to Writing code to these standards has many benefits including the avoidance of bugs where you mix up case, as php variables are case sensitive, better readability, and support for tools that can be integrated into the best PHP code editors to maintain standards and reformat your code It's also easier for others to read Don't use underscores, except in special circumstances. Use camelCase to differentiate words. Some people will use an _ as the first character of a name to indicate private/protected variables in OOP, but I'd avoid them entirely. Underscores are used to name certain special PHP method names, like __construct for example. Your query does not need to return anything from the database other than a count of rows that match your criteria. Just use COUNT(*) for that, and this will always return a result that will either be 0 or something > 0 Have your function return a boolean, so it's clear that it's true/false. Ideally you would use return ($countOf == 1) however, I don't know if you guarantee uniqueness for usernames in your database. You should do that, with a Unique constraint on username, as this would insure that it's impossible to insert more than one row in your admin table with the same username. Not preventing the insertion of multiple admin rows with the same username can lead to terrible bugs in your system. If you do have a unique constraint on username in your admin table, then change the code to return ($countOf == 1). This is also semantics, but the name of your function "loginSuccess" isn't a great name. The function, despite your name does not indicate "login success". All it indicates is that you verified the existence of a row. The concept of a "login" is more complicated and typically involves setting up some session variables and regenerating the session, if you are using sessions generically (for unauthenticated users). A better name for this function would be: function canAuthenticate() or isAuthenticated().
  2. Can you please use the <> button to post your code? I fixed your post this time.
  3. Is your server primarily a forum? Plenty of people use Wordpress, but it is not the best architected, current nor performant platform out there. It also is a blog, and has no built in forum, commerce, or other features, so for that you have to go with a plugin, and perhaps multiple companies you are keeping up with. I say this as someone who has installed, modified and supported a number of Wordpress based sites over the years. Again, if you could tell us more about the site, and what it is for, I'd have more ideas, but it might be better to go with Invision if you can afford a relatively low cost license and subscription for something that has a large installed user base and many users. See https://invisioncommunity.com/ for more information. They have a complete suite of products for communities, which can include commerce and subscriptions, and site building. This forum has used a number of different forum packages over the years and eventually settled on IPB, which we used with very little customization. Another long time commercial competitor is vBulletin, which has hosted a lot of really large internet communities over the years: https://www.vbulletin.com/ With that said, most of the original vBulletin developers created a new product, Xenforo that has a newer more modern codebase. https://xenforo.com/purchase/self-hosted For completely free/open source, there are other CMS platforms like Drupal or the Drupal 7 Fork, Backdrop CMS. They would be similar to Wordpress, only with a modern codebase, and are frequently used as an alternative to Wordpress for people who are more in need of a site building platform. Drupal: https://www.drupal.org/ Backdrop CMS: https://backdropcms.org/ There's a bunch of software you can Demo here: https://www.opensourcecms.com/forum-software/ It includes a list of other Forums that have been around for a while. I have a preference for more current codebases, but then you also take the chance that the projects will stagnate. I do think that some of the newer forums are better architected, and built upon core components like the Symfony components, that have been used in a lot of projects and have robust Unit tests and a large community of users. Along the lines of modern/different is Flarum: https://flarum.org/ I have been watching this project grow for the last couple of years, and one of the things I really like is the way they've coded around modern components, and the open source/sponsorship model. I actually created a forum with Flarum a year or so ago, and found it to be really good, but the project was scrapped. Since that time it's only gotten more mature. It is a flat thread model, driven by tags for categorization, so it might work better for certain types of communities vs. others. Flarum github here: https://github.com/flarum Good luck!
  4. Probably a good decision. I never cease to be suprised by all the different PHP based software in use around the world, but I do think that it may be a challenge to find someone with experience in your forum that isn't a Chinese language speaker, as again, it seems primarily to be used in China. I had never heard of it before, and I've been involved with PHP development and applications for 20 years. The Discuz! forum is now owned by Tencent, and part of a suite of products offered under the "Comsenz" subsidiary. I found a few things for you that might be of benefit to whomever you work with: Main Comsenz site Here is where they advertise and sell their licensed versions Comsenz Github page Has a lot of Discuz! open source releases, but I'm not sure what parts comprise the forum. The newest release I found was December of 2020. I don't know what community this is for, but the best decision for you, if this is not a Chinese language site/community might be to look for a way to migrate to a better maintained platform. I would need to know more about your current site and community to offer better advice, but I would have serious concerns about going forward with something Discuz! based, again dependent on the answer to those questions. With that said, if you want to post for some help we do have some sub-forums that can be used for that here: https://forums.phpfreaks.com/forum/79-freelance-contracts-employment-etc/
  5. The first tip off in this was that somewhere in a prior post, the OP posted the name of the script that was somename.tpl.php. Next you can see from the snippets that there is pure HTML blocks, with a snippet of PHP code inside these mysterious addquote() functions, so you are of course right to have brought that up. Obviously these scripts can't possibly work as is, because the way the addquotes are used within html tags, something else had to be going on. Then we see that inside the addquote calls are small string operations that appear to be outputting various php blocks. So based on this evidence it seems likely that what is happening is that these *.tpl.php scripts are being run through a compiler which compiles them into the final php scripts that drop in and out of php frequently. Since then, of course we were able to identify that this is the forum software Discuz! which is popular in China. I found and posted links to a few threads on the official forum that state that the most current version of Discuz! is incompatible with PHP 8, for whatever reasons.
  6. @ginerjm: Did you read any of the posts I made, specifically the one that pointed out these are templates that get compiled? How exactly can someone make use of the addquote() function in a section of html markup? The solution to the problems here are not to rewrite templates, as they were working fine before the server was upgraded to php8.
  7. So let's review: Site was running PHP 7, and was functional Site is now running PHP8 and is broken 2 Years ago, a programmer did *something* with the forum, but you don't know what that something was... An educated guess would be that they upgraded the version of Discuz to the version that runs under PHP7. Here's something helpful for you: https://www.discuz.net/daily/ This is the page of Discuz! Daily builds. Note that the current version of the forum is 3.4. So that is the newest current version. Here is a thread talking about how Discuz 3.4 does not work with PHP8, and there are people stating due to architecture and plugins, that there is no way it's going to be updated to work with php8. https://www.discuz.net/thread-3852727-1-1.html Based on what I can see, your only viable option is a downgrade of PHP to version 7.4. It will be supported until November, and at that point it will be End of life, so you are not yet in a situation where PHP 7.4 should not be used. Regardless of PHP 7.x's status you are beholden to the support or lack thereof, for Discuz! In conclusion: you need to downgrade the server to PHP 7.4. Don't know what Distro you are using, or what level of control you have over it, but that is what I'd be looking to accomplish at this point. Of course this all makes way more sense now that we've established that: System worked fine with php7.x Broke after upgrade to 8.x
  8. Please don't. This is not a problem you can fix by editting source code. You are running a forum that has templates it compiles and runs. Changing the source code of the forum or these templates, other than via one of their official patch/upgrade packages isn't going to work. There is nothing wrong with the code as it was before, and people were confused into thinking that changing it was going to fix errors, because they did not understand that these were templates that get parsed and compiled into a finalized PHP source. In short, if you changed any files, hopefully you can change them back to what they were originally. It is likely you do need short open tags to be on, but that is not the primary problem. The primary problem is that you are running a version of Discuz! that is incompatible with php7 and needs to be patched. As this forum is not well known in the english speaking world, it's doubtful that anyone here can be much help to you, but I did find a page that appears to link to some patches and upgrade instructions.
  9. I don't know how much simpler I can make it for you. ssh into your server cd to the webroot of the site, based on the webserver (apache?) configuration you are running vim phpinf.php Add the code I provided and save Check the owner and permissions of the file, and make sure they match whatever the other scripts in the directory have navigate to https://domain.xxx/phpinf.php
  10. Looking more closely, this is some sort of forum. Which one, and what version? I figured it out: https://en.wikipedia.org/wiki/Discuz! Was this the commercial version or free version? Is the source available somewhere? Looks like this page has some info on upgrading versions, and possibly links: https://discuz.tistory.com/entry/Comsenz-Discuz-X33-20170101-PHP7
  11. A lot of you have missed the nature of the code. The code being quoted is in templates (notice the name.tpl.php). <title>addquote('<?=$bbname?'.'>')addquote('<?=$navtitle?'.'>')</title> Notice the use of the addquote() function. These templates must be compiled in some way. Really we don't have enough information about the original code, and what it is, and where it came from to understand what is going on.
  12. The way to verify this is to create a script that only has this in it <?php phpinfo(); Put this script in the root of your website and open it with your browser. At the top of the output you can verify which php.ini file is being read in. Then use the browser search to find the short_open_tag setting and verify that it is in fact set to On. This is not the only puzzling thing in the source code you provided, as it appears to me that some sort of template compilation system must be involved, but let's make sure that you haven't missed something in the configuration.
  13. Yes well on your server, you need to find that setting in your php.ini file or add it if it's missing entirely. short_open_tag = On After a change like this you typically have to restart your webserver, depending on what you are running and the configuration.
  14. Great advice from @maxxd. Best practice for any ajax call is to return json. Frequently people have an issue with understanding the Event loop and how that impacts javascript execution. Whatever problem you have, we can't help you understand it, if you don't post your code, and describe the issue.
  15. This site is a tremendous resource: https://phptherightway.com/ In working with MySQL this resource is what I'd recommend, whether that be PDO or MySQLi. If you took a poll of all the developers who regularly visit this community, you will find that we are nearly 100% in favor of PDO over MySQLi, but either one will work. https://phpdelusions.net/pdo I heartily endorse this Free Youtube channel: https://www.youtube.com/c/ProgramWithGio He has a playlist that serves as a free PHP tutorial classl: I have reviewed quite a number of his videos, primarily in order to recommend them to people. I have been a professional software engineer for decades, and have coded with PHP since it was version 3, so I don't take an endorsement like this lightly. If you are a visual learner, and prefer a video course, then I would warrant this is a better and more current course than the vast majority of courses you might find on any of the many e-learning platforms like Udemy.
  16. I'm not sure how we can help you with so little information.
  17. Some good advice and questions from ginerjm and kicken. What is the structure of your customersubscriptions table? As pointed out, the SubRenew column can not simultaneously be an integer (30) AND a subscription end date. I would expect that you would have a DATE, DATETIME or TIMESTAMP column, and use some sort of aging calculation in your query. So for example, let's assume that SubRenew is a MySQL Date column. A query like this would find rows where the renewal is 30 days from today: SELECT * FROM customersubscriptions WHERE SubRenew = DATE_ADD(CURDATE(), INTERVAL 30 DAY)
  18. Use the code tags button to enter your code in the future. I modified your original post this one time. This code is using mysql_. That api was retired long ago. You should be using mysqli_. Your code is insecure and can be exploited with SQL injections. You should be using prepared statements and bind_param. I'm not going to show you fixed code for that. You should modify all your code accordingly and not use php string concatenation. You already have a drop down that searches and finds the entries < date. Why would you need to pre-populate that drop down? At the point you pre-populate it, it's exactly what your results provide. If you want to have a separate drop down of all the users, then do something like: <html> <form name="input"> <input type="date" id="userdate"> <select name="man" id="man"> </select> <input type="text" size="50" id="searchterm"> </form> <div id="content"></div> Create a new javascript ajax call that Fetches the result and populates the "man" select with elements from the mandata.php result. If you want to constrain the list via the same date field, then add that to your mandata query. <?php // mandata.php include('/include/config1.php'); $select = mysql_query("SELECT man_id, man_name FROM manmaster order by man_name"); $data = []; while ($row = mysql_fetch_array($select)) { $data[$row['man_id']] = trim($row['man_name']); } echo json_encode($data); Update your TEST2.php searchterm query, to utilize the selected man_id from the man select in the search WHERE clause. $manId = (int)$_GET['man']; $query = "SELECT man_id, man_name, join_date FROM manmaster where (man_id LIKE '%$searchTerm%' or man_name LIKE '%$searchTerm%') and join_date <= '$kdt'"; if ($manId > 0) { $query .= " and man_id = $manId"; } $select = mysql_query($query) or die('Query not Executed..!..' .mysql_error()); //etc
  19. In my prior reply, I stated to you that this line is not relevant. This is not a function is it? The global keyword is used to inject a global variable into a php function. Unlike javascript, PHP functions have no visibility to global variables, so if you want to use a global variable in a function, then you use global $variable_name. function sayHello() { global $name; echo "Hello $name"; } $name = 'Dhivya'; sayHello(); //Hello Dhivya The code you have shown doesn't do anything of value, so it's hard to understand how this code is being used by you. All you are doing is setting a bunch of configuration settings and a few variables. It looks like you cribbed this code from somewhere for some reason. Let me assume that it is just a config.php file you plan on including in other scripts. Then something like this would make more sense. <?php session_set_cookie_params(0); session_start(); //set_time_limit(0); //ini_set('post_max_size', '500000M'); ini_set('max_execution_time', '3600'); ini_set("memory_limit","2562M"); $config = []; $Localmode = true; // false means server //Check the database connection if ($Localmode) { $var = $_SERVER['DOCUMENT_ROOT'].'/'; $config['SiteAirticalpath'] = "https://psexports.in/"; $config['SiteGlobalPath'] = $config['SiteAirticalpath']."/"; $config['SiteLocalPath'] = $var; $config['SiteImagePath'] = $var."images/"; $config['SiteJsPath'] = $var."js/"; $config['SiteClassPath'] = $var."includes/classes/"; $config['SiteIncPath'] = $var."includes/"; $config['SiteAdminPath'] = $config['SiteGlobalPath']."admin/"; $config['SiteUploadPath'] = $config['SiteLocalPath']."admin/Uploads/"; //$config['SiteTitle'] = ":: Data Grid ::"; ############# DB Config######################## $config['DBHostName'] = "localhost"; $config['DBUserName'] = ""; $config['DBPassword'] = ""; $config['DBName'] = ""; } $config['Limit'] = 10; $config['today'] = date('Y-m-d'); // Don't use an end tag!!!! Things to note: People keep asking you why you are using ob_start()? I removed it because it's a complicated feature, and you have not indicated why you are using it in a config file, or what you are doing that requires it Don't include a PHP end tag in your scripts, especially when they are includes or class definitions for other scripts A helpful comment: This is not a good idea: $config['SiteAirticalpath'] = "https://psexports.in/"; $config['SiteGlobalPath'] = $config['SiteAirticalpath']."/"; //etc. There are 2 types of paths you need in PHP. URL's File system paths Some of these variables seem to be URL's and some seem to be file system paths. For URL's you absolutely don't want to code in a domain. Just use a relative path for this, and let the webserver fill in the domain. For file system paths, there is a more standard way of building variables rather than depending on $_SERVER['DOCUMENT_ROOT'] Let's assume that your "yoursite" directory is the project directory for you web app. Let's assume that this new file you are creating is named "config.php" and is in the yoursite/config directory. You don't want to use that variable, because typically you don't want your includes and classes in "web space" ie. under the webroot directory. You want a structure more like this: / └── var/ └── www/ └── yoursite/ ├── public (webroot)/ │ ├── images │ ├── js │ └── css ├── config/ │ └── config.php ├── src/ │ └── classes └── vendor This is more of a standard structure used by variable PHP frameworks, and accounts for use of composer to integrate component libraries, and generate a class autoloader, which will negate the need for you to require classes yourself. You create a composer.json file for your project and let composer create the autoload file that you then include in your project (perhaps in this config.php file). Here is how you would make a "file system" path variable that points to "/var/www/yoursite" that you can then use to include or load files. <?php // yoursite/config/config.php session_set_cookie_params(0); session_start(); //set_time_limit(0); //ini_set('post_max_size', '500000M'); ini_set('max_execution_time', '3600'); ini_set("memory_limit","2562M"); $config = []; $Localmode = true; // false means server $PROJECT_DIR = DIRNAME(__DIR__); //Check the database connection if ($Localmode) { // Url's $config['SiteImagePath'] = "/images/"; $config['SiteJsPath'] = "/js/"; $config['SiteAdminPath'] = "/admin/"; $config['SiteUploadPath'] = "/admin/Uploads/"; // File Paths $config['SiteIncPath'] = "$PROJECT_DIR/src/"; $config['SiteClassPath'] = "$PROJECT_DIR/src/classes/"; //$config['SiteTitle'] = ":: Data Grid ::"; ############# DB Config######################## $config['DBHostName'] = "localhost"; $config['DBUserName'] = ""; $config['DBPassword'] = ""; $config['DBName'] = ""; } $config['Limit'] = 10; $config['today'] = date('Y-m-d'); // Don't use an end tag!!!! Files that include /config/config.php just need to know their relative path to it. Once included you have the $PROJECT_DIR variable available to use to make file system paths. Again file system paths are only important for PHP functions that require a file system path. They are not urls! Just use relative paths for all your url's. Assume you have a yoursite/public/index.php file <?php //yoursite/public/index.php require_once("../config/config.php"); $data = print_r($config); ?> <h1>Configuration</h1> <p>$PROJECT_DIR: <?= $PROJECT_DIR ?> <h2>$config</h2> <pre><?= $data ?></pre> <a href="<?= $config['SiteAdminPath'] ?>">Admin</a>
  20. Yes, use services you configure. Make sure that you have passed in any related class objects you need to class constructors, including inside controllers.
  21. Let's go back to this as well. What is the query? Do you understand what you are actually doing here? With each fetch you create a new array element in $table that contains that row. So you end up with $table being an array of the rows of the select statement. There is no reason for you to then be trying to access those using the 0 array element. What you *should* be doing is foreach() through $table, as each element should be the single row, but that brings us back to what VehSelection is. if (!empty($table)) { echo '<ul>'; foreach ($table as $row) { echo "<li>{$row['FirstName']} {$row['LastName']} {$row['VehSelection']}</li>"; } echo '</ul>'; } This is a placeholder for how you ought to be foreach-ing through your result set row by row, and finding out what the heck you actually have in VehSelection. I'm unclear why you aren't already doing something like this, unless you are doing a join of some sort, and your issue is that you have multiple rows for each person, because they have multiple vehicle selections. Looking back on the discussion of database design you had with people like Barand, it was pointed out that logically, a one-to-many from Form -> Vehicle should actually be a Many-to-Many resolution between Form >--< Vehicle. Nomenclature and Semantics are highly valuable for an application. Let's look at what your tables should actually be called, and structured: You: Form Should be: person You: Vehicle Should be person_vehicle Missing: vehicle You stated that you didn't want to restructure your database to use something like what Barand provided in great detail, but then also stated this is just a learning exercise. If it's a learning exercise, then please examine what you have done so far, and look at "Refactoring" things that obfuscate your actual requirements. You have a database structure that isn't relationally sound, and has an intrinsic problem -- you don't have a query that provides you a list of all "available" vehicles, from which a user can choose. Thus you are hard-coding that list, even though your problems began with the fact that you don't have that list, and are trying to create it via an array variable. Here's a simplified version of the tables you should have, and the relationships between them. I omitted a bunch of the other "person" fields you have for simplicity. Hopefully you should now see that: SELECT * FROM vehicle can be used to populate your available checkboxes When saving the checked vehicles for a person, upon save you would: Delete all person_vehicle rows where person_id = {the person.id of the person being updated} Insert a new person_vehicle row for each checkbox that is checked Setting person_id to the person you are updating this for AND vehicle_id = to the appropriate id of the vehicle (1 - 3 Barand had a fully fleshed out version of this with queries and a lot more, in an attempt to merge what you had with a many to many as illustrated here. I know the people who have responded to you previously, and they are exceedingly willing to help someone out, but they tend to exit a discussion when they don't see any forward progress, or work on the part of the person being helped. When someone provides you some code, it's up to you to examine it, try and understand it, and determine if you should adopt it, or if it taught you an important concept. Posting a reply that says: "I tried your code but it didn't work" is a great way to get ignored. Show the code you attempted to use, and the specific errors you got. Don't just say: "It didn't work". Given that you are struggling, I am providing the database definition language SQL if you want to start over and use this structure. You would need to alter the person table, to add the other columns you need, but it might be a good reset at this point, allowing you to get some clarity on what you are doing. Whether you use it or not, I hope there are some things in my most recent replies that will help you find the forest through the trees. # ---------------------------------------------------------------------- # # Add table "person" # # ---------------------------------------------------------------------- # CREATE TABLE `person` ( `id` INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, `firstName` VARCHAR(40), `lastName` VARCHAR(40), `birthDate` DATE, CONSTRAINT `PK_person` PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Add table "vehicle" # # ---------------------------------------------------------------------- # CREATE TABLE `vehicle` ( `id` SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(80) NOT NULL, CONSTRAINT `PK_vehicle` PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Add table "person_vehicle" # # ---------------------------------------------------------------------- # CREATE TABLE `person_vehicle` ( `vehicle_id` SMALLINT UNSIGNED NOT NULL, `person_id` INTEGER UNSIGNED NOT NULL, CONSTRAINT `PK_person_vehicle` PRIMARY KEY (`vehicle_id`, `person_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; # ---------------------------------------------------------------------- # # Foreign key constraints # # ---------------------------------------------------------------------- # ALTER TABLE `person_vehicle` ADD CONSTRAINT `vehicle_person_vehicle` FOREIGN KEY (`vehicle_id`) REFERENCES `vehicle` (`id`); ALTER TABLE `person_vehicle` ADD CONSTRAINT `person_person_vehicle` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`);
  22. There are numerous posts to you in this thread. I don't know what your code looks like now. People have provided you refactored code snippets covering many things. At this point, we need a sense of what your current code is *now*. Only you know what that is. I can only advise you to simplify your data structures. Also, it might be helpful for you to start using "camelCase" variable naming, which is a standard convention for php coding. There are many other standards that can help your code readability. See https://www.php-fig.org/psr/psr-12/ A perfect example here is your use of $Vehicle. Rename your variable $vehicle. Start all variable names with a lower case letter. If the variable has multiple words, use camelcase ie. $firstName. What are you trying to do here? What is $table, and why are you accessing element 0? Why are you setting $Vehicle[] = this thing, which actually makes $Vehicle into an array, so that the "thing" needs to be accessed via $Vehicle[0]? If $table[0]['VehSelection'] is an array, then just assign $Vehicle = $table[0]["VehSelection"]; Why were you doing this? You don't need to output the same array inside the foreach! All you needed was to see the value of it *before the loop*. It doesn't change. With that noted, what can be seen clearly, is that despite your claims as to what was actually selected, in all cases, there is only ever one value specified. Even when your form checked "Yacht" and "Plane" this array only contains the single "Yacht" value. You need to determine why that is.
  23. What's your contact.php contain at this point?
  24. Facades are aliases defined in the config/app.php. Look in that file for the "aliases" key and you'll find the mappings. With that said, so long as they remain a part of Laravel, if you want to avoid using them (which is a good idea, especially if you want to have sensible unit tests) then just don't use them. There isn't an option to remove them or disable them entirely, and no plan that I know of to do so. They are a convenience option, but you are not forced to, nor required to ever use a facade.
  25. It was missing a closing param in the snippet I provided.
×
×
  • 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.