Rethinking the Zend Models

July 14, 2009

I'm currently in requirements mode for an upcoming project that should prove to be pretty complex. The current active record/table gateway patterns just aren't going to cut it for the complex business logic that's approaching. I'm starting to lean towards the domain model approach which would increase the initial complexity of the design but allow for the flexibility for future changes and features. The issue is with where to put your business logic? Most of the rails and Zend framework examples show a more active record type pattern which means that the business logic is tied into the persistence storage layer.

For example...
$user = new User();
$user->salary = 100;
$user->updatePayroll();
$user->save();

This works well for smaller apps where your models are tied tightly to your database structure however in my case I'll need to add the application layer above an existing database structure that may have 5 tables per object. For the example above I've diagrammed a possible solution



In this example I've created a User and Company class. Each one holds it's own data and basic operations. There is no sql in these, no direct knowledge of the outside world. Each model has a corresponding Mapper class (data mapper pattern) that knows how to save, find, create and delete it's own model. On top of those layers will sit a service layer that handles the real business logic. The UserPayrollService deals specifically with managing payroll for a user. UserAuthService is strictly for authenticating and logging out a user. As more and more complexity is added such as the need to have a User as part of a workflow engine I can simply create a new service or modify an existing one to implement the new business logic. Some additional benefits are that you can show the diagrams to your stakeholders and they can see concrete evidence that you've captured their business requirements as well as having the components testable on an individual level.

here are some examples of how it could be used...

  1.  
  2. /**
  3. * high level use case for an immediate login and update of salary
  4. */
  5.  
  6. $userAuth = new UserAuthService();
  7.  
  8. if($user = $userAuth->authorize($_request['email'], $_request['password'])) {
  9. $payroll = new UserPayrollService($user);
  10. $payroll->updateSalary(100000);
  11. $currentPay = $user->getSalary();
  12. // currentPay would now equal 100000
  13. } else {
  14. // auth fail
  15. }


  1.  
  2. /**
  3. * example of creating a new user
  4. */
  5. $userMapper = new UserMapper();
  6. if(!$userMapper->userExists($_request['email'])) {
  7. $user = new User();
  8. $user->email = $_request['email'];
  9. $user->firstName = $_request['firstName']
  10. $user->lastName = $_request['lastName']
  11. $userMapper->save($user);
  12. redirect('/home');
  13. } else {
  14. // user already exists
  15. }


Anyone have any thoughts on this implementation? What has served you well?







Comments

RSS feed for comments on this post.

  1. Thomas M says:
    July 14, 2009 @ 15:15 — Reply

    Moving towards splitting Objects into the "pure" classes and mapper objects seems to be the way that the Zend Framework pushes you (see the ZF Getting Started guides here: http://framework.zend.com/docs/quickstart/create-a-model-and-database-table). I do like what you've done above with the separate services layer which adds an additional layer but does a nice job of keeping business rules out of the mapping objects.

  2. John Kleijn says:
    July 15, 2009 @ 11:47 — Reply

    I've been using a Service Layer for an application I am developing as well. I tend to be a little stricter about the boundary though: the Service Layer really is the boundary to the domain model, as diagrammed in PoEAA. I used to create Data Mappers as well, and while IMO they are far superior to Active Record design wise, lately I am using Doctrine because creating mappers for Domain Objects was just getting too time consuming. If there's ever a proper Data Mapper framework for PHP I am sure as hell gonna be in the front of the line though. A note though: AFAIK PHP didn't start supporting multiple inheritance... (your diagram should show aggregation -- or association if you want to be obscure)

  3. Cory Kaufman says:
    July 15, 2009 @ 12:58 — Reply

    "I'm starting to lean towards the domain model approach which would increase the initial complexity of the design but allow for the flexibility for future changes and features. The issue is with where to put your business logic?" Uh... you put your business logic IN your domain objects. If your domain model doesn't contain your business logic, it's not a domain model...

  4. Jim Plush says:
    July 15, 2009 @ 13:31 — Reply

    hi Cory, not sure you understood what I was saying. Of course your business logic is in your domain model however your domain model is not a domain object... a domain model contains things like entities, value objects, repositories, services, etc. Business logic may sometimes be context sensitive. For example a user model. If you try to put a user model in a club it may have certain validation rules compared with trying to put a user into a playground. So in this case the business logic is very much dependent on the context in which it's being used. So you'd most likely want to have your model free of this and have it injected in with a rules object that would be created by the context.

  5. Andrea Turso says:
    July 15, 2009 @ 17:25 — Reply

    Currently there's a open proposal for implementing a component for Domain-Driven Design patterns in the Zend Framework. It seems they're building a configurable Data Mapper. The proposal is available at: http://framework.zend.com/wiki/display/ZFPROP/Zend_Db_Mapper+-+Benjamin+Eberlei I'm not working on the proposal but any help would be appreciated =)

  6. Frank Desmettre says:
    July 16, 2009 @ 09:23 — Reply

    I'm actually using +- this concept of working with the Service layer and Domain model, but instead of the Mapper pattern to make queries, I'm using Db Table classes.

  7. Jose M. Rodriguez says:
    July 16, 2009 @ 21:54 — Reply

    I see two different issues here...One, is domain objects distributed across several tables.The reason for this can be a few, including DB performance.Another, is decoupling bussiness logic from the model classes.Even more:decoupling object definition/object storage/object bussiness logic. While i think your second example is coherent with this view, the first one is a bit confusing to me.I cant see a good reason why getSalary is a method on "User", but updateSalary is a method on the Service. Personally, i prefer having the bussiness logic in the domain objects.I've seen the comment about different "contexts", but still, i'd handle those contexts using derived classes.I think services are more exposed to different contexts than model classes.The first problem (objects distributed in several tables) is more interesting for me, as it's related to my current "experiment".ActiveRecord-like implementations are really limited because they take information from the database to define models..My current experiment takes model information (definition) from files, where (and your blog post gave me the idea! Thanks!) i can define "aliases" for a field, indicating it'd be retrieved/stored in a different table, or even auto-map fields from other tables over the "main" model (the one who owns the primary key), if there's no field name clashing.

  8. Jim Plush says:
    July 17, 2009 @ 05:47 — Reply

    hi Jose, yes I think you're right about the confusing aspect of having a getSalary on user and an updateSalary as a service. perhaps it would be more clear to inject the service object into the updateSalary method of a User instead to be able to change services at runtime. something like... //USER MODEL function updateSalary($service) { // let's assume this method has to do complex calculations when increasing salary such as what state // the user is in, what their tax rate is, etc... $newSalary = $service->increaseSalaryByPercent(5); $this->salary = $newSalary; }

  9. Jose M. Rodriguez says:
    July 17, 2009 @ 07:05 — Reply

    I think that means three things we'd not really like.First, it makes the models aware of the service implementation.In that case, i'd prefer the "increaseSalaryBy..." to be a method on User, so User is calling itself, instead knowing a different object (the service).Second, the parameter $service for updateSalary means it has been created outside, to be used by "User".Dont you think User should create by himself the service object (as mostly all methods would require one)?It'd be something like a ServiceFactory, that you can change on the fly if you're interested in changing services at run-time.And third, i guess in most cases, $service would need a reference to the object model it's working on.I mean, increaseSalaryByPercent will need to know the current user salary,so it'll need a reference to it (not simply a "salary" parameter, i think).So User needs the $service which in turn needs the User...I try to avoid this kind of patterns. Btw, it's great that you mention "state", as i think it's one of the main issues to resolve this kind of problems, and i think it's something the frameworks should handle for us.The other important thing are permissions!

  10. Jose M. Rodriguez says:
    July 17, 2009 @ 07:09 — Reply

    Oh, sorry, just a final thought! Dont you think Service is getting near a Proxy/Fašade class for User? Oh, and sorry if i sound negative!It's not like that at all! I'm really enjoying this issue, i'm very interested in it too! :-)

  11. Jim Plush says:
    July 17, 2009 @ 07:44 — Reply

    hi Jose, I think it comes down to personal preference at that point because you have to create these dependencies somehow and there are only a handful of ways to do it, constructor injection, method parameter injection, setters, service locators, etc... If updating a user's payroll relies on information stored in the persistence layer then it has to query the DB at some point. If updateSalary is a method on the user the user still needs to rely on something outside of itself to get the info it needs to increase it. Which would leave you a few choices Have the updateSalary method call a service to get the salary amount, have the updateSalary method do the db querying itself(not recommended)... I'm still searching for the answer myself as to where this logic should really belong. Ideally User should be as decoupled as possible from the outside domain but to do it's business logic it needs outside information sometimes. I suppose you could remove the burden from the User all together and just have the client use a PayrollService and the User only holds a currentSalary property which would decouple it which is shown in the original example.

  12. Jim Plush says:
    July 17, 2009 @ 11:13 — Reply

    hi Cory, I think my concerns about the $user->updateSalary() method is that if you have a business rule that says "An admin cannot update a user's salary higher than their home state's average cost of living increase, and not 20% higher than any other employee in their department" So the information needed is the salaries of all others in their department (let's assume that's in the users table) but we also need the state's annual cost of living percentage. Let's assume that's in a seperate table or even a web service we have to call. If I pass a userMapper object to the $user->updateSalary($amount, userMapper); the user mapper would have knowledge of not only the users table but it would have to know how to find that other source of information on the state's living increase percentage. That doesn't seem right to me. I've been trying to find out people handle these situations.

  13. London says:
    July 21, 2009 @ 03:06 — Reply

    A function is missing on the diagram. $userAuth->authorize, there is no such function in UserAuthService, UserMapper or User. Where would you put it? UserAuthService? Great Article!

  14. christian louboutin says:
    January 6, 2010 @ 11:47 — Reply

    Comment pending moderation

  15. Louis Vuitton Handbags Replica says:
    January 29, 2010 @ 18:11 — Reply

    Comment pending moderation

  16. gucci handbags replica says:
    January 29, 2010 @ 18:12 — Reply

    Comment pending moderation

  17. Louis Vuitton Handbags Replica says:
    January 29, 2010 @ 19:17 — Reply

    Comment pending moderation

  18. replica cartier watches says:
    March 9, 2010 @ 00:01 — Reply

    Comment pending moderation

  19. fake breitling watches says:
    March 9, 2010 @ 00:03 — Reply

    Comment pending moderation

  20. Renewal By Andersen says:
    March 11, 2010 @ 01:35 — Reply

    Comment pending moderation

  21. GED Online says:
    April 3, 2010 @ 00:29 — Reply

    Comment pending moderation

  22. Online High School Diploma says:
    April 3, 2010 @ 00:30 — Reply

    Comment pending moderation

  23. Homeschool diploma says:
    April 3, 2010 @ 00:31 — Reply

    Comment pending moderation

  24. Get high school diploma says:
    April 3, 2010 @ 00:32 — Reply

    Comment pending moderation

  25. Nation High School says:
    April 3, 2010 @ 00:34 — Reply

    Comment pending moderation

  26. online colleges and universities says:
    April 10, 2010 @ 06:17 — Reply

    Comment pending moderation

  27. SharePoint Courses says:
    April 10, 2010 @ 11:04 — Reply

    Comment pending moderation

  28. acne remedies says:
    April 15, 2010 @ 10:29 — Reply

    Comment pending moderation

  29. one day diet says:
    April 15, 2010 @ 21:55 — Reply

    Comment pending moderation

  30. blu ray ripper says:
    April 18, 2010 @ 04:32 — Reply

    Comment pending moderation

  31. organic mattresses says:
    April 22, 2010 @ 00:49 — Reply

    Comment pending moderation

  32. Business Lawyer Colorado says:
    April 27, 2010 @ 11:36 — Reply

    Comment pending moderation

  33. Muscle Building says:
    April 29, 2010 @ 06:20 — Reply

    Comment pending moderation

  34. graphic design agency london says:
    April 29, 2010 @ 13:04 — Reply

    Comment pending moderation

  35. Puzzles & Word Games says:
    April 30, 2010 @ 02:19 — Reply

    Comment pending moderation

  36. youtube mp3 converter says:
    April 30, 2010 @ 05:33 — Reply

    Comment pending moderation

  37. learn futures trading says:
    May 3, 2010 @ 09:27 — Reply

    Comment pending moderation

  38. male enchancement says:
    May 3, 2010 @ 09:31 — Reply

    Comment pending moderation

  39. make money online says:
    May 3, 2010 @ 22:42 — Reply

    Comment pending moderation

  40. Muscle building program says:
    May 4, 2010 @ 02:25 — Reply

    Comment pending moderation

  41. chaga says:
    May 4, 2010 @ 03:03 — Reply

    Comment pending moderation

  42. Satellite Internet says:
    May 6, 2010 @ 19:26 — Reply

    Comment pending moderation

  43. ev dekorasyonu says:
    May 10, 2010 @ 04:24 — Reply

    Comment pending moderation

  44. Replica Louis Vuitton Speedy says:
    May 10, 2010 @ 18:03 — Reply

    Comment pending moderation

  45. Manolo blahnik says:
    May 14, 2010 @ 04:59 — Reply

    Comment pending moderation

  46. mobilya modelleri says:
    May 18, 2010 @ 14:48 — Reply

    Comment pending moderation

  47. cilt bakimi says:
    May 18, 2010 @ 14:52 — Reply

    Comment pending moderation

  48. 642-067 says:
    May 19, 2010 @ 00:19 — Reply

    Comment pending moderation

  49. 642-062 says:
    May 19, 2010 @ 00:20 — Reply

    Comment pending moderation

  50. law and order season 20 episode 22 says:
    May 21, 2010 @ 04:54 — Reply

    Comment pending moderation

  51. one tree hill season 7 episode 22 says:
    May 21, 2010 @ 04:55 — Reply

    Comment pending moderation

  52. Clasamente says:
    May 21, 2010 @ 11:20 — Reply

    Comment pending moderation

  53. HID lights says:
    May 23, 2010 @ 03:30 — Reply

    Comment pending moderation

  54. up2drive reviews says:
    May 25, 2010 @ 04:12 — Reply

    Comment pending moderation

  55. seo secrets says:
    May 27, 2010 @ 04:07 — Reply

    Comment pending moderation

  56. Christian Louboutin says:
    May 28, 2010 @ 06:23 — Reply

    Comment pending moderation

  57. Abercrombie And Fitch says:
    May 28, 2010 @ 06:25 — Reply

    Comment pending moderation

  58. ugg boots Sale says:
    May 28, 2010 @ 06:26 — Reply

    Comment pending moderation

  59. ghd says:
    May 28, 2010 @ 06:28 — Reply

    Comment pending moderation

  60. vibram five fingers says:
    May 28, 2010 @ 06:29 — Reply

    Comment pending moderation

  61. Tall ugg shoes says:
    May 28, 2010 @ 19:30 — Reply

    Comment pending moderation

  62. Ugg Boots UK says:
    May 28, 2010 @ 19:32 — Reply

    Comment pending moderation

  63. uggs shoes says:
    May 28, 2010 @ 19:36 — Reply

    Comment pending moderation

  64. ugg boots says:
    May 28, 2010 @ 19:39 — Reply

    Comment pending moderation

  65. uggs boots says:
    May 28, 2010 @ 19:41 — Reply

    Comment pending moderation

  66. vibram shoes says:
    May 28, 2010 @ 19:43 — Reply

    Comment pending moderation

  67. Cheap EdHardy says:
    May 28, 2010 @ 19:45 — Reply

    Comment pending moderation

  68. hollister says:
    May 28, 2010 @ 19:48 — Reply

    Comment pending moderation

  69. Jackets says:
    May 28, 2010 @ 21:57 — Reply

    Comment pending moderation

  70. Ugg Classic Cardy says:
    May 28, 2010 @ 22:00 — Reply

    Comment pending moderation

  71. Christian Louboutin Boots says:
    May 28, 2010 @ 22:03 — Reply

    Comment pending moderation

  72. Ben10 games says:
    May 29, 2010 @ 23:00 — Reply

    Comment pending moderation

  73. Adam says:
    May 30, 2010 @ 12:39 — Reply

    Comment pending moderation

  74. memory foam mattress says:
    May 31, 2010 @ 20:58 — Reply

    Comment pending moderation

  75. Revitol Stretch Mark says:
    June 1, 2010 @ 03:50 — Reply

    Comment pending moderation

  76. baby prams says:
    June 1, 2010 @ 23:04 — Reply

    Comment pending moderation

  77. kill lice says:
    June 2, 2010 @ 20:42 — Reply

    Comment pending moderation

  78. Crossbow says:
    June 2, 2010 @ 22:26 — Reply

    Comment pending moderation

  79. asadfahim says:
    June 4, 2010 @ 01:01 — Reply

    Comment pending moderation

  80. Dak jai says:
    June 4, 2010 @ 02:05 — Reply

    Comment pending moderation

  81. virbram five fingers says:
    June 4, 2010 @ 21:03 — Reply

    Comment pending moderation

  82. Free Games Online says:
    June 17, 2010 @ 09:50 — Reply

    Comment pending moderation

  83. asadfahim says:
    June 5, 2010 @ 12:32 — Reply

    Comment pending moderation

  84. 70-528 says:
    June 6, 2010 @ 23:04 — Reply

    Comment pending moderation

  85. Stromlieferant says:
    June 7, 2010 @ 05:17 — Reply

    Comment pending moderation

  86. poker bonus says:
    June 8, 2010 @ 05:29 — Reply

    Comment pending moderation

  87. Outlet Pillow says:
    June 9, 2010 @ 08:01 — Reply

    Comment pending moderation

  88. Video Luna Maya says:
    June 10, 2010 @ 06:14 — Reply

    Comment pending moderation

  89. Farm Games says:
    June 10, 2010 @ 09:54 — Reply

    Comment pending moderation

  90. 2fanonline says:
    June 10, 2010 @ 23:42 — Reply

    Comment pending moderation

  91. kelowna bc says:
    June 11, 2010 @ 04:07 — Reply

    Comment pending moderation

  92. ny limousine says:
    June 11, 2010 @ 04:09 — Reply

    Comment pending moderation

  93. calgary online marketing says:
    June 11, 2010 @ 04:12 — Reply

    Comment pending moderation

  94. rent edmonton says:
    June 11, 2010 @ 04:14 — Reply

    Comment pending moderation

  95. stress at work says:
    June 11, 2010 @ 04:15 — Reply

    Comment pending moderation

  96. YourNetBiz says:
    June 11, 2010 @ 09:26 — Reply

    Comment pending moderation

  97. YourNetBiz says:
    June 11, 2010 @ 09:29 — Reply

    Comment pending moderation

  98. London Limousine says:
    June 11, 2010 @ 09:31 — Reply

    Comment pending moderation

  99. acuvue oasys says:
    June 11, 2010 @ 09:35 — Reply

    Comment pending moderation

  100. air jordan shoes says:
    June 11, 2010 @ 19:58 — Reply

    Comment pending moderation

  101. nike air force 1 says:
    June 11, 2010 @ 19:59 — Reply

    Comment pending moderation

  102. cell phone battery says:
    June 12, 2010 @ 00:54 — Reply

    Comment pending moderation

  103. Dubai Web Application Development says:
    June 12, 2010 @ 04:10 — Reply

    Comment pending moderation

  104. Water Proof Jackets says:
    June 13, 2010 @ 08:17 — Reply

    Comment pending moderation

  105. SEO says:
    June 14, 2010 @ 04:25 — Reply

    Comment pending moderation

  106. Search Engine Optimization says:
    June 14, 2010 @ 05:12 — Reply

    Comment pending moderation

  107. Custom Sticker printing says:
    June 15, 2010 @ 00:12 — Reply

    Comment pending moderation

  108. Pregnancy Miracle says:
    June 15, 2010 @ 04:35 — Reply

    Comment pending moderation

  109. Indonesia Furniture Handicraft Wholesale Marketplace says:
    June 15, 2010 @ 10:21 — Reply

    Comment pending moderation

  110. Louis Vuitton handbags says:
    June 16, 2010 @ 00:20 — Reply

    Comment pending moderation

  111. Louis Vuitton handbags says:
    June 16, 2010 @ 00:30 — Reply

    Comment pending moderation

  112. iPhone app says:
    June 16, 2010 @ 06:35 — Reply

    Comment pending moderation

  113. christian louboutin shoes says:
    June 16, 2010 @ 08:33 — Reply

    Comment pending moderation

  114. food pyramid says:
    June 16, 2010 @ 22:22 — Reply

    Comment pending moderation

  115. online traffic school Los Angeles says:
    June 16, 2010 @ 22:26 — Reply

    Comment pending moderation

  116. cheap insurance says:
    June 16, 2010 @ 22:29 — Reply

    Comment pending moderation

  117. ski goggles says:
    June 16, 2010 @ 22:31 — Reply

    Comment pending moderation

  118. Jillian Michaels diet pills says:
    June 16, 2010 @ 22:33 — Reply

    Comment pending moderation

  119. Promotional Gifts says:
    June 17, 2010 @ 05:23 — Reply

    Comment pending moderation

  120. Promotional Products says:
    June 17, 2010 @ 05:41 — Reply

    Comment pending moderation

  121. Corporate Gifts says:
    June 17, 2010 @ 05:49 — Reply

    Comment pending moderation

  122. seotrafficstorm.com says:
    June 17, 2010 @ 23:53 — Reply

    Comment pending moderation

  123. Bvlgari jewelry says:
    June 18, 2010 @ 01:21 — Reply

    Comment pending moderation

  124. hermes belts says:
    June 18, 2010 @ 01:22 — Reply

    Comment pending moderation

  125. evening dresses says:
    June 18, 2010 @ 08:33 — Reply

    Comment pending moderation

  126. Microsoft Office 2007 says:
    June 19, 2010 @ 02:16 — Reply

    Comment pending moderation

  127. kobe bryant shoes says:
    June 19, 2010 @ 05:20 — Reply

    Comment pending moderation

  128. kobe bryant shoes says:
    June 19, 2010 @ 05:22 — Reply

    Comment pending moderation

  129. kobe bryant shoes says:
    June 19, 2010 @ 05:23 — Reply

    Comment pending moderation

  130. fat burning furnace scam says:
    June 19, 2010 @ 13:00 — Reply

    Comment pending moderation

  131. Luxury car rental Miami says:
    June 20, 2010 @ 02:11 — Reply

    Comment pending moderation

  132. Forex Robot says:
    June 20, 2010 @ 16:51 — Reply

    Comment pending moderation

  133. Mortgage Loans says:
    June 20, 2010 @ 16:55 — Reply

    Comment pending moderation

  134. Weight Loss Diet says:
    June 20, 2010 @ 16:56 — Reply

    Comment pending moderation

  135. Quality Top Site says:
    June 20, 2010 @ 16:57 — Reply

    Comment pending moderation

  136. Weight Loss Tips says:
    June 20, 2010 @ 16:59 — Reply

    Comment pending moderation

  137. Idahoagbell says:
    June 20, 2010 @ 17:01 — Reply

    Comment pending moderation

  138. General Weblog says:
    June 20, 2010 @ 17:02 — Reply

    Comment pending moderation

  139. Online Games says:
    June 20, 2010 @ 17:03 — Reply

    Comment pending moderation

  140. Golden Casino Games says:
    June 20, 2010 @ 17:05 — Reply

    Comment pending moderation

  141. Personal Blog says:
    June 20, 2010 @ 17:06 — Reply

    Comment pending moderation

  142. Promo Codes says:
    June 20, 2010 @ 17:08 — Reply

    Comment pending moderation

  143. Wallpapers Nintendo says:
    June 20, 2010 @ 17:11 — Reply

    Comment pending moderation

  144. Diacetate says:
    June 20, 2010 @ 17:12 — Reply

    Comment pending moderation

  145. Colonial Life Insurance says:
    June 20, 2010 @ 17:15 — Reply

    Comment pending moderation

  146. Cheap Hotels says:
    June 20, 2010 @ 17:18 — Reply

    Comment pending moderation

  147. free music download mp3 says:
    June 20, 2010 @ 21:13 — Reply

    Comment pending moderation

  148. birthday message says:
    June 20, 2010 @ 23:28 — Reply

    Comment pending moderation

  149. Replica Jewelry says:
    June 21, 2010 @ 00:45 — Reply

    Comment pending moderation

  150. Desks says:
    June 21, 2010 @ 06:25 — Reply

    Comment pending moderation

  151. Download Full Movies says:
    June 21, 2010 @ 22:40 — Reply

    Comment pending moderation

  152. Sticker Printing says:
    June 21, 2010 @ 22:43 — Reply

    Comment pending moderation

  153. Background Check says:
    June 21, 2010 @ 22:45 — Reply

    Comment pending moderation

  154. watch free movies says:
    June 21, 2010 @ 22:46 — Reply

    Comment pending moderation

  155. Rent Movie Online says:
    June 21, 2010 @ 22:47 — Reply

    Comment pending moderation

  156. john says:
    June 21, 2010 @ 23:55 — Reply

    Comment pending moderation

  157. tracy says:
    June 21, 2010 @ 23:56 — Reply

    Comment pending moderation

  158. Phentermine 37.5 says:
    June 22, 2010 @ 03:58 — Reply

    Comment pending moderation

  159. ceramic sink says:
    June 25, 2010 @ 00:19 — Reply

    Comment pending moderation

  160. Andri says:
    June 26, 2010 @ 05:12 — Reply

    Comment pending moderation

  161. 32 lcd tv says:
    June 26, 2010 @ 06:46 — Reply

    Comment pending moderation

  162. ceramic watches says:
    June 26, 2010 @ 07:11 — Reply

    Comment pending moderation

  163. herpes in mouth says:
    June 27, 2010 @ 04:39 — Reply

    Comment pending moderation

Leave a Comment

Line and paragraph breaks automatic, HTML allowed: <a href="" title="" rel=""> <abbr title=""> <acronym title=""> <b> <code> <em> <i> <strike> <strong>

Comments disabled due to spammers being losers that lead sad lives.