Jump to content

Strider64

Members
  • Posts

    465
  • Joined

  • Last visited

  • Days Won

    12

Everything posted by Strider64

  1. if ($_FILES['image']['size'] >= 44040192) { $errors[] = 'File size must be less than or equal to 42 MB'; } Simply check the file size and throw and throw an error if it is too big. I would also on the HTML page state the maximum file size allowed to upload. You could also try to compress the file, but that gets more involved.
  2. SwiftMailer is also another good one, I use it and it's very simple to use and has good community support: Just a small section of a small script /* create message */ $message = (new Swift_Message('A email from ' . $data['name'])) ->setFrom([$data['email'] => $data['name']]) ->setTo(['example@email.com']) ->setCc([$data['email'] => $data['name']]) ->setBody($data['message'], 'text/html') ->attach(entity: Swift_Attachment::fromPath('https://www.example.com/assets/images/img-logo-003.jpg'));
  3. Well, the path won't be "hidden" even if you get it to work properly as anyone can get the path by looking at the HTML once the image is displayed. That is if I am understanding you properly?
  4. require 'initializations.php'; if(isset($_POST['add_cat'])) { $cat_obj->add_category($_POST['cat_title']); header("Location: admin/category.php"); exit; } To me there should be some kind of check to see if the add_category method/function to see if it actually did what it say. The way it's written now it blind faith that it worked and the reason for the header redirect? This is what I'm talking about require 'initializations.php'; if(isset($_POST['add_cat'])) { $result = $cat_obj->add_category($_POST['cat_title']); if ($result) { header("Location: admin/category.php"); exit; else { echo "Oops, something went wrong"; } } of course something in return true or something like that needs to be in the add_category. If require "header.php" is causing the problem then maybe the above needs to be in a configuration file or sessions needs to be used? As the above then isn't at the level at should be at.
  5. Well, if you just update the $_SESSION on page1 directly, but go straight to page 2 then how is it going to update? It will update if you go to page 1 first then page 2. I hope I'm making sense? You need to update it in a configuration file of some sort or it as a set option where you can't go to any other pages if you update ppp?
  6. Hmm? I didn't not know that as I'm a iPhone user. I find it strange that android devices would do that. I think a work around would to check the email.value to see if it's empty?
  7. Well, I would if the errormessage is the trigger then just wipe out the input value (email.value = "";) for the email, have it required and show the error message. HTML5 won't allow a user to proceed. Maybe? if (/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email.value)) { errorMessage = 'Email contains invalid character/s'; email.value = ""; } Though it really isn't checking totally for invalid characters just the proper format. (That's what I'm concerned about) I think most people are pretty careful in typing their email address.
  8. const emailIsValid = (email) => { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); }; email.addEventListener('change', () => { let status = emailIsValid(email.value); console.log('Email Address', email.value, 'Status', status); if (!status) { email.value = ""; email.placeholder = "Email Address is Invalid!"; email.style.borderColor = "red"; email.focus(); } else { email.style.borderColor = myBorder; sendEmail.email = email.value; sendStatus.email = true; } }); It's still best to check it server side and HTML5 make it required.
  9. I for one have found using Grids and Flex to reduce the CSS file size a lot as you really don't use that much CSS when using Grids/Flex, plus it's very easy change the layout of the website. It's well worth redoing the CSS using grids/flex and it's a tad bit better than doing it from the ground up, but not by much. Here's a small example of my css (Actually it's SCSS, but it's just a processor version of CSS) - Though looking at this example it looks like just plain CSS in this portion. /* Approximately the size of an iPad Pro 12.9in 1024px */ @supports (grid-area: auto) { @media screen and (min-width: 64em) { .site { display: grid; grid-template-columns: 1fr minmax(19.2em, 44.80em); grid-template-areas: "header header" "nav nav" "sidebar main" "footer footer"; justify-content: center; } .masthead { background-image: url(../images/img-header-001-1024.jpg); } .registerStyle { display: grid; grid-template-columns: 1fr 1fr; grid-template-areas: "email email" "first last" "screenName telephone" "password1 password2" "birthday submitForm"; justify-content: center; } .first { grid-area: first; margin: 0 0.625em; } .last { grid-area: last; margin: 0 0.625em; } .screenName { grid-area: screenName; margin: 0 0.625em; } .telephone { grid-area: telephone; margin: 0 0.625em; } .emailStyle { grid-area: email; margin: 0 0.625em; } .password1 { grid-area: password1; margin: 0.3125em 0.625em; } .password2 { grid-area: password2; margin: 0.3125em 0.625em; } .birthday { grid-area: birthday; text-transform: capitalize; margin: 0.3125em 0.625em; } .submitForm { grid-area: submitForm; button { float: right; } } } } Another thing that will bog down the CSS is having LARGE image files and having redundant CSS. I also would stylize for smartphones first and work yourself up from there when it comes to CSS responsive web design.
  10. I would look into using Grids and/or Flexbox. I personally like grids and once you learn it then you find out how simple it can be in my opinion.
  11. You need three things for pagination to work : Current Page being displayed Total Count of Records The number of pages to be displayed Then you have to figure out the offset public function offset(): float|int { return $this->per_page * ($this->current_page - 1); } Sorry, that's as far as I can go as that looks like WordPress and that is something that I don't do, but I'm sure WP has some built-in features for pagination. Maybe someone else will be able to help you better?
  12. Personally, I just write functions that I try to do one thing and send it back to the main program. Here's an example of what I'm talking about $query = "SELECT username FROM " . static::$table ." WHERE username = :username"; $stmt = Database::pdo()->prepare($query); $stmt->execute(['username' => $username]); if ($stmt->fetch(PDO::FETCH_ASSOC)) { $data['check'] = true; return $data; } $data['check'] = false; return $data; I check the username against the database table then send and array back. Yes, I know it only has one index in the array, but then I can use that for other code like a validation array for example? This might help or it might not? I just find it easier not to have too many things going on at once.
  13. My suggestion is to find a good PHP tutorial and have error reporting turned on (which should be part of the tutorial). As for what you are trying to do try to keep it simple. TRY to keep most of the PHP on top and the HTML on the bottom of each page. Here's an example of what I mean and try to comment your coding as it will make sense later on when you go modify or help you out when you go work on it later on. Top /* * Set the class to of the record (data) to be display * to the class then fetch the data to the $record * ARRAY do be displayed on the website. If an * update has been done then update database * table otherwise just fetch the record * by id. */ if (isset($_POST['submit'])) { $cms = new CMS($_POST['cms']); $result = $cms->update(); $id = $_POST['cms']['id']; } elseif ($id && is_int($id)) { $record = CMS::fetch_by_id($id); $cms = new CMS($record); } else { header("Location: index.php"); exit(); } Bottom <form id="formData" class="form_classes" action="edit.php" method="post" enctype="multipart/form-data"> <input type="hidden" name="cms[id]" value="<?= $id ?>"> <input type="hidden" name="cms[user_id]" value="<?= $_SESSION['id'] ?>"> <input type="hidden" name="cms[author]" value="<?= Login::full_name() ?>"> <input type="hidden" name="cms[date_updated]" value="<?= $date_updated ?>"> <input type="hidden" name="action" value="upload"> <input class="form_image_upload_style" type="file" name="image"> <br><br> <label class="heading_label_style" for="heading">Heading</label> <input class="enter_input_style" id="heading" type="text" name="cms[heading]" value="<?= $cms->heading ?>" tabindex="1" required autofocus> <label class="text_label_style" for="content">Content</label> <textarea class="text_input_style" id="content" name="cms[content]" tabindex="2"><?= $cms->content ?></textarea> <button class="form_button" formaction="delete.php?id=<?= $id ?>" onclick="return confirm('Are you sure you want to delete this item?');">Delete</button> <button class="form_button" type="submit" name="submit" value="enter">submit</button> </form> Just my helpful addition to the conversation (I hope).
  14. Object-oriented Programming does add better security as you can make the code protected or private, but any code is hack-able. The biggest security threat is between the user and the website as you don't what the user might try. It can be like playing whack-a-mole with them at times. My best advice is never trying to write your own security code, by that I mean like not writing your own password algorithm. Let that be done by PHP internal security functions/methods or a TRUSTED 3rd-party source. Just my .02 cents.
  15. Another pattern you might want to look into is Active Record Design Pattern. That is what I use as it's database data driven and once the you get the insert, update and delete working it's basically just sending the right query or sql to the database. The view is usually another class. It's nice for a small website, but I wouldn't want to use it on a big project though it does lend itself to modifications more easily in my opinion and being a little more haphazard for people who like that aspect of coding. 😃 Though MVC does lend itself to better to structure than ARD and some people consider Active Record Design Pattern an anti-pattern. Though I disagree with that as if it was the case then you might as well stick to procedural coding in my opinion. Some more info -> https://en.wikipedia.org/wiki/Active_record_pattern
  16. Strider64

    New CMS

    I personally design the CMS first by that I mean I do a mock-up of what I visualize what the CMS is going to look like by creating a static HTML page with CSS. That way I know how it's going to look like and the setup of the PHP. Here's a visual description on what I'm trying to get at: (Obviously this is after the PHP being added) <?php foreach ($cms as $record) { ?> <article class="cms" itemscope itemtype="http://schema.org/Article"> <header itemprop="articleBody"> <div class="byline" itemprop="author publisher" itemscope itemtype="http://schema.org/Organization"> <img itemprop="image logo" class="logo" src="assets/images/img-logo-004.png" alt="website logo"> <h2 itemprop="headline" class="title"><?= $record['heading'] ?></h2> <span itemprop="name" class="author_style">Created by <?= $record['author'] ?> on <time itemprop="dateCreated datePublished" datetime="<?= htmlspecialchars(CMS::styleTime($record['date_added'])) ?>"><?= htmlspecialchars(CMS::styleDate($record['date_added'])) ?></time></span> </div> <img itemprop="image" class="article_image" src="<?php echo htmlspecialchars($record['image_path']); ?>" <?= getimagesize($record['image_path'])[3] ?> alt="article image"> </header> <p><?= nl2br($record['content']) ?></p> </article> <?php } ?> The main thing to take away from all of this is the naming of the variables as they are consistent to the database table: create table cms ( id int auto_increment primary key, user_id int null, author varchar(160) null, page varchar(255) default 'index' null, thumb_path varchar(255) null, image_path varchar(255) null, Model varchar(255) null, ExposureTime varchar(255) null, Aperture varchar(255) null, ISO varchar(255) null, FocalLength varchar(255) null, heading varchar(60) null, content text collate utf8_unicode_ci null, date_updated datetime null, date_added datetime null ); I would start off using procedural PHP when creating the first CMS and it still can be very robust. A lot of planning beforehand can save a lot of headaches later on. Didn't realize this was an old thread as I'm still waking up. 😁
  17. Yes sir. I did give this serious thought. I was able to make everything work by simply serializing $_POST data, and retrieving it when the $_GET request is made. But then I read about all the dangers and pitfalls of serializing $_POST (not to mention, doing so would be uncultured and uncivil). I made a list of pros and cons: mySQL Cons I am not very good at mySQL (writing the simplest prepared statement requires about 3 hours debugging afterwards) It's pretty easy writing PHP to access the MySQL database table. It just takes practice and actually writing the code. I have to worry that one day a visitor will decide to Post too much inventory data and my varchar(255) columns would be too small. (If I used "text" or "blob" I would be worried my table is taking too much unnecessary pace, greenhouse gases, etc.) Unless you are the size of Facebook, I don't think you have anything to worry about taking up space in a db table. If I knew mySQL as well as you do I'd have given full mySQL a shot. ...but I know my place. Find a good tutorial, practice coding and actually write the code. I didn't start off right away knowing how to code in PHP and everyone here has started off as a newbie. I didn't learn PHP until I was in my 50s and now I am not only able to access MySQL using PHP PDO, but can do the following: /* * This is the update that method that I came up with and * it does use named place holders. I have always found * updating was easier that creating/adding a record for * some strange reason? */ public function update(): bool { /* Initialize an array */ $attribute_pairs = []; /* Create the prepared statement string */ foreach (static::$params as $key => $value) { if($key === 'id') { continue; } // Don't include the id: $attribute_pairs[] = "{$key}=:{$key}"; // Assign it to an array: } /* * The query/sql implodes the prepared statement array in the proper format. */ $sql = 'UPDATE ' . static::$table . ' SET '; $sql .= implode(", ", $attribute_pairs) . ', date_updated=NOW() WHERE id =:id'; /* Normally in two lines, but you can daisy chain pdo method calls */ Database::pdo()->prepare($sql)->execute(static::$params); return true; } Commenting your code also help reinforcing what you have learned.
  18. The following simplifies this for me to understand.
  19. I personally like using the Fetch API as it's pretty straight forward and pretty darn easy to use (once you get the hang of coding it): Here's an example from my contact page: /* Success function utilizing FETCH */ const sendUISuccess = function (result) { //console.log('Result', result); if (result) { d.querySelector('#recaptcha').style.display = "none"; submit.style.display = "none"; notice.style.display = "grid"; notice.textContent = "Email Successfully Sent!"; notice.style.color = "green"; message.style.display = "grid"; d.querySelectorAll('form > *').forEach(function (a) { a.disabled = true; }); } }; /* If Database Table fails to update data in mysql table */ const sendUIError = function (error) { console.log("Database Table did not load", error); }; const handleSaveErrors = function (response) { if (!response.ok) { throw (response.status + ' : ' + response.statusText); } return response.json(); }; const saveRequest = (sendUrl, succeed, fail) => { fetch(sendUrl, { method: 'POST', // or 'PUT' body: JSON.stringify(sendEmail) }) .then((response) => handleSaveErrors(response)) .then((data) => succeed(data)) .catch((error) => fail(error)); };
  20. Do a echo "<pre>" . print_r($result, 1) . "</pre>"; die(); to see if you are getting any results.
  21. $pwd = password_hash($data['password'], PASSWORD_DEFAULT); unset($data['password']); try { $query = 'INSERT INTO users (fullName, username, status, password, security, email, date_added) VALUES (:fullName, :username, :status, :password, :security, :email, Now())'; $stmt = Database::pdo()->prepare($query); $result = $stmt->execute([':fullName' => $data['fullName'], ':username' => $data['username'], ':status' => $data['status'], ':password' => $this->pwd, ':security' => 'newuser', ':email' => $data['email']]); } catch (PDOException $e) { /* * echo "unique index" . $e->errorInfo[1] . "<br>"; * * An error has occurred if the error number is for something that * this code is designed to handle, i.e. a duplicate index, handle it * by telling the user what was wrong with the data they submitted * failure due to a specific error number that can be recovered * from by the visitor submitting a different value * * return false; * * else the error is for something else, either due to a * programming mistake or not validating input data properly, * that the visitor cannot do anything about or needs to know about * * throw $e; * * re-throw the exception and let the next higher exception * handler, php in this case, catch and handle it */ if ($e->errorInfo[1] === 1062) { return false; } throw $e; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "\n"; // Not for a production server: } If you really want to make sure there can be no duplicates then create an unique index for the username and throw an PDO exception if a duplicate is found. Though I think this would only be useful for a busy busy website.
  22. There's is a way check the "inside" of an image file $contents = file_get_contents($file['tmp_name']); $position = strpos($contents, '<?php'); return $position !== false; HOWEVER, it's a memory hog and doesn't work very good for large image files as you would need something more robust than the strpos() function. I personally don't allow image uploading other than myself who I trust. 😄
  23. To me that would be more ideal for a client side web app (like JavaScript) than a server-side app (PHP). They wouldn't have to use the back button at all and you could even use JavaScript, Ajax and PHP if you want to use a MySQL table. To give you an idea here is an example of a trivia game that I wrote for my website - https://www.miniaturephotographer.com/game.php I'm still developing it, but it works pretty darn good and you can do all sorts of things to it.
  24. You're not echoing out the content <h4><?php the_title(); ?> </h4> should be <h4><?php echo the_title(); ?> </h4> /* or this */ <h4><?= the_title() ?> </h4>
×
×
  • 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.