Jump to content
Larry Ullman's Book Forums

theaceofthespade

Members
  • Posts

    24
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by theaceofthespade

  1. I just wanted to point out that, by storing the cart/wishlist in the database, you can easily offer people complete permanence with an optional user login. If you store your cart/wishlists' session key in the user database, you can simply reset the cookies to match those whenever they log in. Likewise, when they create an account, you can store them then, so that the cart they had is seamlessly converted to the cart associated with their account. At that point, the user account is optional, without disrupting any site flow, or scaring away potential customers. Just an observation I wanted to share from a project I'm working on.
  2. I'm going to have to disagree. The builder pattern assumes a similar construction for all the different variants. This is not the case. All of the products use a database table to store their relations to various products and systems. Different types of promotional abstractions use the database to store things differently. At this point, you gain absolutely no advantage by implementing a building pattern, vs completely separating the way that this data is extracted in the various protected constructors. Likewise, an abstract factory is one level of abstraction too far. There is never any need to have multiple factories going, as all the promotions are only one or two descendants down from the original promotion class. There is simply not enough variation between them to warrant the overhead and additional code of an abstract factory. On the other hand, in this implementation, a simple factory pattern needs only to select which descendant class to instantiate based on the code passed to it, and then let that class handle it's own unique functionality. It's extremely light weight, easy to change, and completely modular - to add a new type of promotion, all I have to do is extend the promotion class in a new file, drop it in the folder, add it to the list, and it just works. What is it exactly that you don't like about the factory pattern in this implementation? I have to say though, after typing all of that out, it occurs to me that we are probably talking past eachother at this point. I will consider posting code, but will most likely wind up posting skeletal/pseudocode instead.
  3. I tried to post a comment to that, but mistakenly hit trackback, so I'm not sure where on your site it went... so... sorry bout that... Anyway, I wanted to ask, how do you use Express checkout without leaving your site?
  4. If you're on shared hosting, they may restrict you from having your own htaccess files.
  5. I just finished implementing Paypal's Express Checkout with fairly little difficulty. It runs on a very similar set of principles, as Larry stated, and there are even settings to make it that much more like website payment's pro. Either way, you will still have to do all of the IPN integration. Now, forgive me if I misunderstood you, but let me clarify: to my knowledge, if you do checkout with paypal express checkout, the user will always have to leave the site to log into paypal. By default, when you do express checkout, you pass info to paypal, including a total estimate, the user logs in, confirms that they want to do the order, and then is returned to your site with a token id. At this point, the transaction is not official, and it is up to you to communicate with paypals site that you want to make the payment official. However, if you would like it to behave more similarly to website payments standard, there is an option in the express-checkout account to have the payment completed on paypal's site.
  6. Without more code, here are your three most likely possibilities I can think of: 1) $e is not actually being defined in the script 2) $e is defined somewhere inside of a conditional, so it doesn't necessarily get defined 3) The snippet you posted is inside of a function, and therefore within a different scope.
  7. While I know that nothing can make it truly impossible to oversell, it did make a big difference implementing paypal's "Express Checkout" system, vs website-payments pro. It takes the user's info, pre-approves the purchase based on an estimate of the total cost, and then returns them to the site, along with token/session info. Then, from your site, you actually authorize the payment. So I can check the stock literally right before I tell paypal that I want to commit to the pre-approved transaction. That being said, I still installed an email warning list if any product inventory goes negative.
  8. @Larry - thanks larry, that means a lot! @Antonio - This is very interesting, thank you for your thoughts! Regardless of a working system or not, it would be foolish to ignore someone's input - and in this case, it even happens to be good input! While I still need to maintain the factory pattern for the discount codes (I'll get to that in a moment), I think that your idea of a criteria class is quite excellent, and will implement that. I definitely agree that the checking criteria contains it's own functionality that would be better off self contained. Another thing that you made me realize is that I need to refer to these as "promotions" rather than "discounts." The promotion codes have to be in their own classes because the same software is being used across multiple store sites, with various different requirements and components. While it is certainly true that only one class is needed for percentages and amounts, there are other discounts, or more specifically, promotions, that are more specific to their native systems. For example, I have one store that wanted to be able to offer free gift-wrapping with a certain code. The same store needed to be able to include a downloadable coupon that could be printed out immediately after the order was placed and used in a physical store. Another store needed to be able to include a special product in the order when the code was used (they wanted it to be controlled by the inventory manager without showing up in the store). Yet another needed to award digital currency when a certain code was used (although sadly, it looks as though this project mite not get to see the light of day anyway!) The factory pattern allows me to modularize these different types of promotion codes, and mix and match them for different store implementations, without having to cram huge amounts of code into the "discount" class (which, as I said, I am definitely going to change to the "promotion" class) which isn't needed by all the sites. And of course, all of these include entire systems by which the users of the site are able to create/edit codes themselves.
  9. That is a good point on the factory pattern. However, the reason that I implemented it is that I have a large variety of different types of discounts, for various different stores. They are capable of handling any type of discount one could imagine, even with incredible conditions, like conditionals, rebates, buy x get x free etc. I have several different store systems across 3 or 4 different websites at this point, and I needed to be able to drop in the discount code files without having to alter the checkout implementations, and it seemed like the best way to make it that portable. It basically winds up that I have $cartCode = DiscountCode::factory("THECODE"); $cart->applyDiscountCode($cartCode); And can add new types of discounts across the board.
  10. if you use "require_once" as I suggested, it will resolve your problem. You are including your mysql file once in the index, and then again in your login script.
  11. Again, sorry for the lack of response. So I wound up going a simpler route, although there is certainly not perfect from a design standpoint. Basically, I decided that I was going to force each product to have only one set of options. If the product has more than one set, then it just needs to be split into products. From there, I just made an option table, forced all products to automatically have one product_option, and then set it so that the name of the options was stored in the product table. So for tshirt sizes, there would be the product options "large","medium","small", each with their own price and stock data. Then the product row that they were all linked to would have the "option_name" column set to "Shirt Size" It's one of those solutions where I'm happy with how simple it is, but at the same time know that it pays for that simplicity with expandability. there is a forseeable circumstance where limiting myself to the single option set is not optimal.
  12. It depends on your site. You should include any sort of environment data, any functions that you use on almost every page, and any variables you need pre-defined. If you use object oriented stuff, it should include your autoloader, and if you do any custom error reporting, you should throw that in there as well. Mine for my site includes my autoloader, a constant that contains the url of my page, a constant that contains the domain name for my page, a short script for forcing the user to the https version of the site if they are supposed to be there, error handling routines, and a static class that safely handles the post, get, and cookie data. Recently, I added something that sets the default timezone as well. Your include file should not send anything but headers to the user. It should not echo anything at all; don't include a ?> at the bottom of the file either.
  13. A neat trick to help avoid this is, in your include files, leave off the closing ?> so that it is impossible to have trailing whitespace
  14. firstly, it can't hurt to do: if( isset($_POST['var']) && whatevercondition($_POST['var']) ) php will not evaluate the second condition if the first is false. I also would do something like strlen>minpaswordlength instead of empty. Just looking at your code, we really need your actual login page to see what you're talking about (form included). But off the top of my head, for the logging in without anything, have you looked at your database to see if you have an entry with a blank email/password?
  15. I am tackling this right now actually. My solution is insanely complicated at the moment, because it is supposed to handle all sorts of different types of coupon codes, but I'll explain the basic discounts here. My solution is designed for an object oriented environment, but it could easily be applied outside of that. So, I have a cart class. The cart can have a coupon code object applied to it. The coupon codes are generated by a static factory function instead of a constructor. You pass it the string from the coupon code, and it looks it up in the database. The database stores the code, it's code type, start and end dates, and an amount value, which is nullable. The code type is an integer, which is aligned with an array in the parent class. Right now, there is: "PERCENT" =1 ,"STATIC" =2 ,"FREE_SHIPPING"=3 Percent is of course a percentage off of the total, static is a static dollar amount off, free shipping is free shipping. If it's percent, the amount is interpreted as a percent discount, whereas if it's a static type, the amount is interpreted as a dollar amount. While this is designed around being object oriented, you could easily do it with simple functions, and a switch-case structure, which determines the appropriate discounts based upon the type. I actually have a whole other table, which contains links from the codes to the products, for individual discounts etc, but that is a whole other store for another day!
  16. The way you have this set up, you can't have "login.inc.php" and "mysql.inc.php" included in the same file without generating this error. To get around this, try using "require_once" instead of "require" any time you need to include the "mysql.inc.php" file. This is a pretty decent practice to follow anyway, although you should probably be more conscious about when you are connecting to the database. To take it a bit further, however, it's arguably good design to not allow the login file to do the connecting, and instead just have it check and see if you are connected before it tries to execute. This way you are keeping the database connection functionality separate from the login functionality, since the login is obviously not the only thing using the database connection. But then again it's not necessarily bad design either, just some food for thought.
  17. In xampp, it's in the settings you get to from the sidebar's homescreen. It comes with it's own test certificate (it will light your browser up with warnings like a christmas tree, but it works for testing). So I haven't messed with lamp, but I did find this: http://www.phpjoel.com/2011/04/07/installing-ssl-using-openssl-on-a-wamp-localhost/
  18. Whew, sorry I haven't been on in so long - been coding stores! Larry, I can't recommend your books enough! I figured I'd come here and give an update/get some input on my solution. So, I wound up structuring my order/payment flow a little bit differently. As a side note, my whole store is object oriented. When the person goes to place an order, it does not actually enter the system as an order until the system has in some way been notified of payment. In the case of Paypal, I set up the "express checkout." As soon as they complete the order, it is entered into the system at the same time as the first transaction. This is also the point at which I deduct the products from the site inventory. I wound up using this approach because, as stated above, I needed to be able to ensure that there was no over-selling of stock. The moment before they click "submit order" on my site (express checkout goes my site->paypal->my site), I check that everything in their cart is valid and in stock, then submit the info to paypal, then record the response. As soon as I get a response that says the payment was not rejected (even if it's just pending), I add the order and reduce the stock. From there, I leave it up to the site administrators whether or not to cancel the order if it's been pending for too long. I have a page in the admin section that shows them how long orders have been "pending payment," and highlights/notifies them after a month of being pending. If they decide that the order is just not going to make it through, they can mark it as canceled, the products will automatically be added back to the store inventory, and the appropriate financial info is handled (depending upon their payment method). At this point, short of two people ordering within milliseconds of each-other, there is no chance of stock being over-sold. Of course, if anyone can see any sort of foreseeable downfall to this, vulnerabilities, etc, any input is much appreciated.
  19. What are the virtues of having the "User" table separate from the "Order" Table, rather than having all of it combined, aside from being able to insert the info bit by bit? I'm referring specifically to the second example. Considering that customer info is repeated, is there really any need for a one-to-many relationship from the customer to orders table? Does it make that much difference to make them separate, or am I missing something?
  20. I'm just sort of guessing here, but I would assume it's so that you could have a record of the transaction to manually match up to a user in your database. If the transaction went through, but you left no record of it because an error occurred while obtaining the user id, then you would wind up holding someone's money and being none-the-wiser.
  21. Greetings Abigail, thanks for your input! The stores I'm working on are for an overstock company, and a small arts business. Once a product has been sold, there is no guaranteeing that there will be more stock at a later date. The phone-order idea is a great idea! I'll be sure to post anything I find through that avenue, thanks!
  22. Thanks for the response! That would certainly be easy to implement, but I feel like that still has the same inherent problems, with products popping in and out of availability. Plus, the success would depend entirely upon your conversion rate. If %100 percent of people who put something in their cart wind up following through to checkout, then that would work great; however, that's not going to be the case. I also don't like the idea of putting any sort of pressure onto the consumer. At the moment, I'm still leaning toward reducing the available stock once the order is placed (very last thing before processing payment), even if the payment hasn't cleared, and then allowing the admin to cancel the order at their discretion, (if a payment is taking too long, for example), and thereby return the items in the order to the available stock.
  23. Firstly, an amazing book as usual! Your ability to break down code into English is invaluable and unparalleled! I am working on a site with sometimes limited inventory (perhaps as few as 4 of something). The client expects to sell in "bursts," ie, they send out an email, and people flood the site to purchase the items, effectively creating a race condition. Obviously, I can't have someone purchasing something that someone else has already purchased, so I have to remove it from the available stock as soon as possible. On the other hand, it is vital to the success of the system to minimize events where items are tied up in incomplete orders, ie, orders that have been placed but not cleared financially. I am not locked into paypal or any credit card authentication system for checkout yet, as choosing which to use largely depends on the resolution of this issue. At present, I feel that using a system like Authorize.net is my best bet, as I would have the chance to stop the sale right up until the moment that the user is submitting the financial data and thus making the sale final. My client would like to offer both paypal and on-site credit card payments, but is not insistent upon it. Any solutions or thoughts on this would be greatly appreciated.
  24. I came on with a similar question. First off, amazing book!! I'm working on a website for overstocked goods. The option sets for various products are unpredictable, so simply creating an outright table for the options is not viable (one product my be a shirt in multiple sizes, another mite be a blanket with various thread counts, etc). Either way, it has to keep track of the options, and each options stock. First, I thought to do a table for the options - each product would link to an option group (or vice versa), and each option in the options table would have a name, a price, an sku modifier, and a stock amount. That way, if you had a shirt, you could link it to the options small, medium, and large, with their various data, and if you had a sheet, you could link it to its various thread counts, and it could all be held within the same table. This is the only way I've come up with to solve the issue. I was also considering just making a serialized php array, but that's something I try to avoid no matter what, so for now I'm left with the above solution. Am I on the right track here? Any advice?
×
×
  • Create New...