Jump to content

gizmola

Administrators
  • Posts

    5,871
  • Joined

  • Last visited

  • Days Won

    139

Everything posted by gizmola

  1. So according to Mac's link, as I surmised, you can't relay mail directly from your server via it's mta. Port: 25 SMTP Authentication: False or none SSL or Secure Connection: None Server or Host: The relay server you need to use depends on the type of hosting and script you use. This is apparently why your script doesn't work. It is trying to send mail to your local mta via the smtp protocol. There should be instructions on what the relay server is for your email domain. It is not going to be localhost, but rather some domain name they specify. Changing the script to use the right server should allow it to work. While this has nothing to do with your contact script, as far as the other issues with deliverability, one main issue from the report you provided is that DKIM is not being used. There is nothing you can do about that, as DKIM has to be implemented by the email administrator. I don't know if there is any possibility of having it supported by GoDaddy hosting or not, as it is non-trivial. If you want to know more about it, this article does a good job of explaining the basics so you have a frame of reference: https://www.uriports.com/blog/introduction-to-spf-dkim-and-dmarc/ I don't know the purpose of your server or what types of emails you intend to send, but they will not have a high deliverability score, and thus will likely be spam filtered by some email systems. For the purposes of a contact page, that is not a concern, as you can whitelist your address, but if you will be sending regular/automated emails from your domain, you may encounter problems with other people receiving them. Candidly, Godaddy is not a well regarded hosting company, although many people do use it. Hopefully at very least you are not using shared hosting.
  2. In general, images are best stored either on a filesystem or in a CDN like cloudfront or akamai. It's enticing to store them in a database that you are already using, but it's highly inefficient. Blob storage in databases is expensive considering that you must query the result from the database in order to then return it to the client. What most people do instead is have a table that stores a path to the image, so that you can have the best of both worlds.
  3. I should probably add that the secret to determining if recursion allows for something elegant, is to determine if you can reduce the problem down to a discrete examination. In the case of my solution, the insight I depend upon is that I only need to check the outer 2 letter of the string in order to determine if it *might* be a palindrome. Another solution using this insight could also be coded using map and reduce. It also needs to be said that the overhead of recursion means that it is almost never employed, although there are some problems involving nested arrays where I see people using it in PHP.
  4. There are no doubt a number of different solutions to this. Here is one. So one way to look at it is that in order for a word to be a palindrome, letters offset from each other must be the same. Treating the word as an array, that means you can check word[0] against word[word.length-1] , and if those characters are the same, then it could be a palindrome. If not, it is definitely not a palindrome. Now if you then remove the outer characters (using shift and pop), and check again, this same process is also valid on the remaining inner string. Thus you have an opportunity to use recursion. You can continue this process until the string you are checking has 1 character or less remaining. If you get to the point that the array of characters has no characters remaining then it was a palindrome. Here is an implementation of this idea: function isPalindrome(word) { let palindrome = true word = word.split("") //console.log(word) if (word.length < 2) { return palindrome } palindrome = (word[0] === word[word.length-1]) if (!palindrome) { return palindrome } word.pop() word.shift() return isPalindrome(word.join("")) } const words = ["HelloWorld", "abba", "abcdecba", "a", "oio", "nevermoreromreven"] words.forEach(word => console.log(`"${word}" is a Palindrome: ` + isPalindrome(word)))
  5. The error you are getting is saying no smtp connection could be made to localhost. Does your server have an mta running (sendmail or postfix)? Does your server have any sort of firewall running that might be blocking port 25? Email configuration for a domain and server is a highly complicated endeavor that involves many different moving parts. It also depends a lot on the type of hosting you have. When you state that "it's sending and receiving other emails" I don't know what that means exactly in your case. There are many things this could be, all of which require a fair degree of system administration skills, and an understanding of your hosting. One possible issue is that "localhost" is not being resolved by your server to the loopback address. About the only suggestion I could make, pretty much as a hail mary attempt, would be to change your script to use '127.0.0.1' instead of 'localhost'. Assuming this is a linux based server, you can check the contents of the /etc/hosts file to see if there is a proper entry mapping localhost to that ip. For mail to have any degree of deliverability direct from a domain, requires lot of things to be setup correctly. This site is an excellent aid in testing and diagnosing deliverability: https://www.mail-tester.com/ If GoDaddy is acting as your MTA, then I would expect that your scripts would be delivering mail to a godaddy mail server, and not to localhost at all, so again, email is complicated, and we really don't have enough information to provide more than a couple of educated guesses as to what your issue is.
  6. I'm sure there are many such libraries but this one has been used by many people: https://github.com/ddeboer/imap This one comes up as the most used in packagist: https://github.com/barbushin/php-imap
  7. This looks like homework .... I understand the idea, and it smells like a recursive exercise, which teachers love, and yet are rarely employed due to the huge overhead involved in building a functional stack. 2 things here: You have code that "looks" ok. Obviously you are having some problems with it, but you have no examples or debugging of what doesn't work Do you expect us to set up an environment and run your code and debug it for you? See #1. So in general, yes, I would say that yes, if this is an assignment, this is an exercise that should involve recursion. This code looks very suspect for a few reasons including that repeat is not shown to be initialized anywhere, and it should be local to the running function on the stack: $repeat = $repeat * $data[$i]['number']; Just off a quick browse of your code, you are trying to combine the reading of the array with the processing of a repeat/close_repeat. You want a recursive function that only handles the repeat/close cycle. So what you need in terms of variables is: index of global array temporary array built, which is return when function completes and is returned to be added to the finalized array. Inside your recursive function you can encounter 1 of 3 things: An entry which you add to your temporary array A repeat, where you calls the function recursively having advanced the start/end index an end_repeat where you duplicate the temp index the #repeat times and return it you increment the index internally, so you need to pass this by reference One trap you probably have is trying to control the other process with a for loop. What you actually want is a repeat--until pattern where you will process starting with index=0 until the index = count(array) -1. PHP does not have repeat/until but it does have do..while, so that is what your control should be based on. Hopefully this leads you to a solution, otherwise, again we need specific code, with your debugging and specific problems you are having with select sections of the code.
  8. I provided you a solution that should work. Just keep in mind that rules are processed in order. You need this "catchall" to come at the end/after all the other more specific rules or those other rules will never be reached. So you want: www rewrite rule specific pseudo directory rules like your news/ the catchall to *.php Just looking at where you are going with this, having a routing class and using a front controller pattern where you route everything through index.php which acts as a router, is essentially the direction you are taking your site from the look of it. You can make everything simpler and cleaner by either porting to symfony or laravel (which have many benefits in terms of access to all the other features of those frameworks) or just integrate some routing class into what you have. This looks like a possible solution for you: https://phprouter.com/ With that said there are myriad others, but that one appears to be functional, simple and minimal.
  9. The courses I mentioned in the other reply cover design and include layouts with flexbox and grid. https://scrimba.com/learn/flexbox https://scrimba.com/learn/cssgrid You want to keep in mind that your goal is to end up proficient with making "responsive layouts" so you should be at some point absorbing some of the ideas involved in how to have a design that adapts to device viewport. Of course you need to get down the basics first and then I think you can add in the elements that really make things responsive. Responsiveness involves a judgement call on your part... what things should shrink or be hidden at smaller sizes. When it's a mobile phone user, do you stack a menu or replace it entirely with a hamburger button? You figure these things out based on your preference. I mentioned Kevin Powell recently. Go through the free Scrimba course they have with him instructing. If you particularly like his style, then you might want to look at his paid courses. Some are free and some are paid either directly or through a Scrimba membership. In my opinion the Scrimba membership gets you the most bang for your buck, but he has a course on flexbox you can enroll in directly: See links to his various course at https://www.kevinpowell.co/courses/ Powell has this "free" course: https://courses.kevinpowell.co/conquering-responsive-layouts It is being done as a 21 day challenge, with new material being released day by day. The course is just being released now, and only has the first few days of content, but it could be a really good place for you to start. I personally like the idea of Scrimba for people learning as it gets you right to where you want to be within the courseware environment. It also has a very active Discord community you should join if you go the Scrimb route. You can also take the scrimba files and download them, fork your solutions etc, and they host all that for you. But of course for your own projects you need a local environment and code editor, and he is likely presenting that material in a local environment using Visual Studio Code and the "Live Server" extension. One nice thing about Visual Studio Code is that you can add the PHP Intelephense plugin and use it for your PHP development as well. Most pro PHP developers are using the PHPStorm commercial editor, but VSCode is the choice of javascript developers at this point, so if you're doing a lot of both, then VSCode + Intelephense is a good alternative. Powell's free responsive course has an early lesson on the environment and that might be helpful to you to see what he's using for his course.
  10. Ease of use vs security is a never ending battle. Try to opt for the simplest solution that also works. You can either act as custodian (allows for you to aid a user when they forget/misplace something) provide no custody, thus insuring a compromise of your system doesn't compromise user assets You can't do both. Not knowing enough about this system, I would question the nature of the vouchers themselves. Does your system know the value and when something is redeemed? You might have a customer service feature that would allow someone to make a new voucher to replace a lost one? That mght be an alternative, but would require your system to have the necessary information and controls available to you to determine the status of a voucher, and be able to revoke/replace it.
  11. Just a note: please don't use imgur links. That site is a mess, and the forum allows you to attach and insert images into your posts. I editted your question to do that. It's better for everyone to have the content referenced here. As I answered this in the bootstrap thread you made, I'm not going to repeat my comments but they are relevant. These days, layouts are a lot easier to do using flexbox and/or grid. I would also suggest using an html/css/js sandbox for your prototyping/etc. Here's an article with quite a list of different ones. I did already mention scrimba to you, so you can certainly use that as well. https://www.sitepoint.com/code-playgrounds/
  12. I'm not 100% sure what you trying to do. I tried to extrapolate that you are looking for "/something" and wanting to rewrite that to "/page.php?slug=something". Options +FollowSymLinks -MultiViews RewriteEngine On ErrorDocument 404 /404.php RewriteCond %{HTTP_HOST} ^domain.com$ RewriteRule ^(.*)$ https://www.domain.com/$1 [R=301,L] RewriteCond %{HTTP_HOST} !php$ RewriteRule "^([A-Za-z]+)" "page.php?slug=$1" [L,QSA] Since you didn't provide examples of what other rules this "broke", this is my best guess. An important addition is that this rule won't run for existing *.php scripts.
  13. The PHP process may not be able to write to the /var/log directory. Assuming it's the apache user that php is running as in this case. Connect to the container and check out the perms for /var/log.
  14. The first question I would have for you, is do you have a solid "non-expert" understanding of html5 and css? That is what I would highly recommend to get down 1st. This is a good free course to go through, that is all done interactively in the Scrimba environment: https://scrimba.com/learn/introhtmlcss It's taught by Kevin Powell who is one of the better known css teachers I know of, and has an extensive set of video tutorials on youtube. Before you go further down any path, I would recommend you watch this video, which really helps you get an idea of what these different techs provide you from a design/UI standpoint: If you watch enough of this you'll get to the point where he compares some options (vanilla css, vs tailwind vs Material UI (MUI) vs Bootstrap, and declares: "Yeah Don't use Bootstrap. It's 2022 and you know better!" Nonetheless, this is a professional design guy who has worked for various well known companies and is very experienced, so I won't be an absolutist about this, but you should at least go into whatever phase of learning you are entering knowing more about this. I personally use Bootstrap every week for a client I work for, and I would certainly love to be able to move on from it now, but I'm stuck with a giant code base that is tightly integrated with it. At least do your research. Absolutely you should be using the latest version if you do use it. I have found that it is actually pretty easy to use in most cases, however this guy has a complete course on it, and most of his videos are really good: One thing to keep in mind is that Bootstrap does have places where to really take advantage of some of the widgets, you also need to have a working understanding of javascript, in order to integrate it with what you are doing. That is going to be true of many other css frameworks and approaches. It also needs to be said, that whether or not you should be using Bootstrap is a significant question, as there are other css frameworks that have become extremely popular, most notably Tailwind CSS. There are a number of other popular css frameworks, many of which are better suited to customizing the look and feel of things, or have a philosophy that is a bit more modern than what bootstrap has (given that Bootstrap is pretty old at this point, even though it has been updated). Here's an intro to tailwind and a complete course by a guy who has a lot of courses on Udemy, and was actually paid to make a professional level course on Tailwind that is again free on youtube. It is project based, but only one project in this case. If you like Tailwind as an approach then you probably want to look at TailwindUI and/or DaisyUI which build upon Tailwind and are closer to what you would get with much of Bootstrap.
  15. There are functions and an entire database class you didn't include that is mysterious. Here's a simplified functional spec Initialize your variables, get initial statistics Get the largest timestamp value in the database. At the end you can use this to update any rows that need to be cancelled because there was no importer entry This assumes that every row has some sort of timestamp row. It appears that way, but you didn't provide the format. Import the file Check that there are entries. You don't want to cancel the entire userbase because the import was flawed Get pre-import statistics for active/cancelled One group by query for this will give you both numbers. SELECT COUNT(*) as count_of, memberStatus FROM Members GROUP BY memberStatus No need to pre-sort import data foreach through the import data SELECT id, status from Member where id = import id If row is found Based on ID, update status, timestamp If it's an actual datetime/timestamp you can do this with column = NOW() This guarantees that a found ID column gets its timestamp updated regardless of the status Based on status add to appropriate bucket rejoined was still status 1 if row not found Add new member Update to new member count When complete, SELECT COUNT(*) FROM Members WHERE "timestamp/updated" column is <= original timestamp you queried during initialization. These are the rows you now need to cancel, so store in your summary array as needed UPDATE Members SET status = 2 WHERE WHERE "timestamp/updated" column is <= original timestamp you queried during initialization At this point you should be able to make your final reporting. Count the arrays for new/ongoing/rejoined. Use the cancelled count# you got from the summary. You probably want to get an initial count of all existing rows via SELECT COUNT(*) but if all rows have a status of 1 or 2, then you can just use the counts from the GROUP BY query summed together.
  16. I'm not sure what you want from us, given an outline of your requirements and a basic list of steps. You know what you want to do, and the code doesn't work right or count right, so that means you have bugs. We can't debug your code without seeing it. Here are a few thoughts based on list of steps: This is a terrible idea. There is no reason to update rows of the entire table to inactive, only at some later point to set them back to active. Don't change rows you don't need to change. This is really unclear. What is the format of the "import" array? Are there ID's? I don't see how you could classify anyone as a "Left user". If they were not found, then they should be added as a new user. Thus all users are either found (existing) or not found (new). It seems like there are a number of baked in assumptions here that aren't clear, starting with where this import file comes from. What constitutes "active" state in this system? What exactly is the format of the import file?
  17. And everything I wrote previously still applies. let json_array = {} json_array.excludes = [] // Use array method json_array.excludes.push("a") json_array.excludes.push("b") //array syntax json_array["excludes"].push("c") console.log(json_array) I Updated the codepen as well with this example code.
  18. Personally, I would recommend uninstalling xamp and using docker. There are a lot of projects out there that offer a docker-compose that orchestrates a lamp environment for you. Devilbox is a massively complete project that offers a myriad of different configurations (not just lamp), but there are many others, not to mention lots of tutorials showing how you can create your own. I even made a project myself to support some of the work I do. I have seen a good deal of discussion of people who primarily make Laravel apps using Laravel Sail, but it can be used for any php project afaik. With that said, if you absolutely must have something similar to what xampp provides, people seem to like Laragon.
  19. the push method is for an array. Adding to objects can be done in a few ways: Using array syntax: obj['property'] Using "." notation: obj.property obj = { 'foo': ['apple', 'banana'], 'getFoo': function() { return this.foo } } console.log(obj.getFoo()) obj['bar'] = ['red', 'green'] obj.foobar = function() { return this.foo.concat(this.bar) } console.log(obj.bar) console.log(obj.foobar()) Example code in this codepen.
  20. In the documentation about external fonts, it specifically provides an example using google fonts. Try adding this to your initialization of dompdf: $tmp = sys_get_temp_dir(); $dompdf = new Dompdf([ 'logOutputFile' => '', // authorize DomPdf to download fonts and other Internet assets 'isRemoteEnabled' => true, 'isFontSubsettingEnabled' => true, 'defaultMediaType' => 'all', // all directories must exist and not end with / 'fontDir' => $tmp, 'fontCache' => $tmp, 'tempDir' => $tmp, 'chroot' => $tmp, ]); $dompdf->setPaper("A4", "portrait"); $dompdf->loadHtml($_template, "UTF-8"); $dompdf->render(); $dompdf->stream(time() . ".pdf", array("Attachment" => false));
  21. Yes recently (v7) PHP was changed so that you can have a private constructor in a class meant to be used statically, so that it is impossible to instantiate an object of that class externally using the 'new' keyword. This is not related to object cloning. Object cloning requires the 'clone' keyword. <?php $obj1 = new stdClass(); $obj1->foo = 'Object1'; $obj2 = $obj1; // $obj1 and $obj2 point to same object. They "reference" the same object echo $obj1->foo . PHP_EOL; // Changing $obj2 changes the underlying object pointed to by both variables $obj2->foo = 'Object2'; // Changed the property of $obj2, and thus This prints 'Object2' echo $obj1->foo . PHP_EOL; // This time we use clone // Object 3 is an independent object, only the properties were copied $obj3 = clone $obj1; // Changing $obj3 does not change $obj1/$obj2 $obj3->foo = 'Object3'; echo $obj1->foo . PHP_EOL; // Still prints 'Object2' echo $obj3->foo . PHP_EOL; // Prints object3 Looking at a private constructor example, does this affect the use of new? Yes. You can't instantiate it with new, only using a static method. <?php class Test { private ?string $name; private ?string $guid; private function __construct(?string $name = null) { $this->name = $name; $this->guid = uniqid('', true); } public static function makeTest(?string $name = null) { return new static($name); } public function getName() { return $this->name; } public function getGuid() { return $this->guid; } } $foo = new Test(); This triggers a runtime error: Fatal error: Uncaught Error: Call to private Test::__construct() However, using makeTest() to create an object, does this somehow prevent variable assignment or clone behavior? Not at all! class Test { private ?string $name; private ?string $guid; private function __construct(?string $name = null) { $this->name = $name; $this->guid = uniqid('', true); } public static function makeTest(?string $name = null) { return new static($name); } public function getName() { return $this->name; } public function getGuid() { return $this->guid; } } $obj1 = Test::makeTest(); echo "Name:" . $obj1->getName() . PHP_EOL; echo "Guid:" . $obj1->getGuid() . PHP_EOL; $obj2 = Test::makeTest('Object2'); echo "Name:" . $obj2->getName() . PHP_EOL; echo "Guid:" . $obj2->getGuid() . PHP_EOL; $obj3 = $obj2; echo "Name:" . $obj3->getName() . PHP_EOL; echo "Guid:" . $obj3->getGuid() . PHP_EOL; $obj4 = clone $obj2; echo "Name:" . $obj4->getName() . PHP_EOL; echo "Guid:" . $obj4->getGuid() . PHP_EOL; You will see something similar to this: Name: Guid:6372930b031f27.11028500 Name:Object2 Guid:6372930b032385.75458089 Name:Object2 Guid:6372930b032385.75458089 Name:Object2 Guid:6372930b032385.75458089
  22. I have a bit over 14k rep at SO with 99.9% of that from answering questions. I've all but given up on going there, as they have made the site, despite protestations to the opposite, miserable for new or inexperienced developers and for anyone trying to help them, especially in the #php tag. There are a few overzealous mods who have made it their mission to criticise or close questions from novices, even going so far as to attack people answering these questions. It's gotten to the point that there is really no point in answering anymore questions, because the questions get closed or pointed to existing answers even when there is a substantive details that make the pre-existing question irrelevant. SO's been going in this direction for quite a while, but to read that someone would be threatened with expulsion from SO for asking too many questions, is mind boggling.
  23. Hopefully you learned a couple of important principles throughout this exercise: html id's should always be unique in a page. For this reason they are rarely used for styling, again unless the styles being bound to them are also unique to that element in general classes are much better for styling groups of things, and as Barand showed, for attaching a related event listener.
  24. Thanks for reporting this! Thanks for fixing @requinix
  25. I want to throw in my 2 cents here: Why use an abstract class? You have a number of concrete classes that will inherit attributes and behavior from this common ancestor. The ancestor itself is not specific enough to be an actual thing. In your case you should decide -- is Product "abstract" for your use? It doesn't seem to be, but by no means should you have a concrete class named Products! If you want to use plurals, great, but most often people will use singular naming. It seems that you did this Product vs Products thing just to get around the naming issue, which should tell you that you are on the wrong track here. In Products, your constructor just sets a lot of of attributes, all of which could easily be part of the Abstract Product class. Move that into the Abstract class. One obvious thing missing is the idea of what "type" of Product an individual Item is. Your specific getFur, getDVD etc, are just completely off base and shouldn't exist. The database should have a type or item_type column in it that describes the type of item. This would typically be constrained by a table which has a row for each possible item type, used as a foreign key for your products or items table. What's an alternative approach here? MVC would tell you that you could use a "Model" class. Generically a model class knows how to map data from a database table into attributes. We know from your code that table is named "skandi" So taking a step back, how about thinking about what you might need to facilitate the data from a table. What might you have generically? <?php abstract class TableModel { private $databaseConnection; protected $database; protected $table; protected $primaryKeys = []; protected $attributes = []; private $data = []; protected function getDatabase() { return $this->database; } protected function getTable() { return $this->table; } protected function getPrimaryKeys() { return $this->primaryKeys; } protected function setAttributes(array $attributes) { $this->attributes = $attributes; } public function getAttributes() { return array_merge($this->primaryKeys, $this->attributes); } public function setDatabaseConnection($databaseConnection) { $this->databaseConnection = $databaseConnection; } protected function getDatabaseConnection() { if (!$this->databaseConnection) { throw new \Exception('Database Connection Uninitialized'); } return $this->getDatabaseConnection; } protected function getFullTableName() { return '`' . $this->getDatabase() . '.' . $this->getTable() . '`'; } public function getAllRowsSQL() { // Just an example to show the possibilities. return 'SELECT * FROM ' . $this->getFullTableName(); } } class Product extends TableModel { protected $database = 'yourDb'; protected $table = 'skandi'; protected $primaryKeys = ['id']; protected $attributes = ['sku', 'name']; } $product = new Product(); $conn = 'SomeDbConnection'; $product->setDatabaseConnection($conn); echo $product->getAllRowsSQL() . PHP_EOL; echo implode(',', $product->getAttributes()) . PHP_EOL; You most likely wouldn't have a getAllRowsSQL method, but I provided it just to give you an idea of where you might go with this. Since TableModel is generic for any type of table, you can concentrate on how to generically query data from any table and load it into the $data attribute. You could also consider things like insert/update and delete. All the other attributes you have which are specific to the skandi table, might lead you in the direction of an Interface or possibly an interface with a set of common "Product" traits. I only mention this because you seem to be on the path of needing to explore those features. In general, interfaces allow for passing a de-coupled object into a class as a parameter. Rather than have the specific insert/update/delete routines in a TableModel, you might instead want your abstract TableModel class to implement an interface that a separate database management class might want to call instead. getFullTableName() is an example of a method that might be helpful in a database management class, where you would pass a Product object into and have it do the specific SQL calls, using things like the table name, keys and attributes.
×
×
  • 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.