Jump to content
Larry Ullman's Book Forums


  • Content Count

  • Joined

  • Last visited

  • Days Won


theaceofthespade last won the day on October 29 2011

theaceofthespade had the most liked content!

Community Reputation

9 Neutral

About theaceofthespade

  • Rank
  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!
  • Create New...