A Qcodo based CMS/ecommerce framework
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

308 lines
16 KiB

12 years ago
  1. %
  2. snapshot: Thu Jul 30 2008
  3. As of this snapshot, Quasi is still in a very early stage - this release is functional in some basic
  4. facilities and totally unfinished in others, it is provided mostly as a preview and to give
  5. those who are curious a look at the general architecture.
  6. That said, you can make a website with it - but if you don't know what you are doing, don't. There
  7. has been very little attention given to security issues and although it may be fine there is no
  8. guarantee that it isn't full of holes. It is also likely to be a bit buggy. However, Quasi is designed
  9. first to be a developer's system; I have put quite a lot of effort into attempting to design a framework
  10. that is easy to work with, extensible and robust. It is also based on a toolkit (QCodo) that supports
  11. very rapid application development so if you are a web developer you may find it quite useful even
  12. as it is now.
  13. Customization that you want to have independant from the core release can be done in a directory
  14. called "local/" in the same directory as "core/" - it should mirror the structure of "core/"; Quasi will
  15. look there for stylesheets. assets, modules and the autoloader will look there for classes in files
  16. named with the convention <classname>.class.php. Stylesheets will cascade from core through
  17. contrib to local, class will be loaded in reverse falling back on core.
  18. Code generation happens in "generated/", ORM subclasses are in [core|contrib|local]/orm and
  19. metacontrols in [core|contrib|local]/meta_controls. The subclasses will be created if they do not
  20. exist but not overwritten, generated classes WILL be overwritten during generation. You can
  21. add to the database and code-generate and move your local subclasses to "local/orm" and Quasi
  22. will find them as needed. The base classes will always be under generated/[orm|meta_controls].
  23. Panel and form drafts also go under generated/ - and generated/panels contains a mildy altered
  24. index page that serves as "admin/" until Quasi gets a "real" administrative UI. You can put a symlink
  25. in the root directory for convenience or surf to <quasiroot>/generated/panels/ to use the admin UI.
  26. There are a couple of changes to QCodo's default set up that are needed to get things running - they
  27. are minor and detailed in the README.txt.
  28. If you are interested in helping, find quasicms at sourceforge.net and have a look around - there are
  29. and will be many things to do and many ways to help. Bug reports are welcome.
  30. Have fun!
  31. --erik
  32. %
  33. The following is a casual treatment of some parts of the Quasi architecture - it is both unfinished and
  34. incomplete. Much more information is available in the comments of the classes in the CMS
  35. engine and the various modules and of course, if you really want to learn about it, "Read the source, Luke..".
  36. <CMS Engine>
  37. Briefly, the engine runs off a single controller script: index.php and its template. This is an
  38. instance of class IndexPage which extends QForm. All requests are processed by this form.
  39. The form inspects the Request URL and determines the Page name from the first part after
  40. the script name. It then loads a corresponding Page object and passes it to a new PageView.
  41. The PageView knows already which general blocks (divs) are active and it loads all ContentBlocks
  42. associated with the basic default areas, creating new ContentBlockViews for each and rendering
  43. them in order in the template. ContentBlocks go on to do the same for ContentItemViews,
  44. MenuViews (which in turn load MenuItems) and Modules.
  45. The difference between a ContentItem (or Menu/MenuItem) and a Module is that a Module
  46. is active - that is, it does more than passively present data from the database. Any display
  47. that requires processing to display or recieves input that calls functions is a Module. These
  48. are created by writing a module class and placing in the modules subdirectory - it must be
  49. named following the convention of the other modules in this directory. Then enter it in the
  50. database with the class name and assign it to a ContentBlock - both things done through
  51. the admin interface. You can then go on to have the Module class include other classes,
  52. perform actions, create new panels, dialogs, input, etc. as desired. The final action is to
  53. ensure that the new module is required() at the top of the IndexPage. The engine will load
  54. it into the associated content block.
  55. ContentItems and Menus are similar without the writing of a class - one simply creates a
  56. new item or menu in the admin interface and enters the desired content. Content may
  57. contain HTML, a WYSIWYG editor is planned. After saving the content or menu, it is
  58. assigned to a ContentBlock. Easy, huh? ;)
  59. Menu items are the same process but they are assigned to a Menu.
  60. ContentBlocks are assigned to a page and given a location on the Page: Header, RightPanel
  61. CenterPanel, LeftPanel or Footer - or one of the ExtraDivs. This is the default, however, it
  62. is trivial to change this by editting PageView and its template and entering other names
  63. in the block_location_type table in the database - there is no interface for this as yet (and
  64. remember to run the code generator after this!).
  65. The administration interface is, er, basic at the moment - it lives in drafts/dashboard; those
  66. of you familiar with QCodo will know what it consists of which is the generated access to
  67. the ORM objects from the database schema. Much of the logic of Quasi is in the database
  68. schema so this is not trivial, but it is as yet an area needing a layer of abstraction to be more
  69. user friendly. For now, you get the "power user" interface ..
  70. </CMS Engine>
  71. What follows are general notes about the architecture of the modules, lists, views and other
  72. misc features in the CMS.
  73. <Account Management>
  74. AccountManagerModule:
  75. The Account page has a module that parses the PageParameters to determine which Account module
  76. to load. Eg. for Addresses/ it will acivate the AccountAddressesModule. This module in turn contains
  77. an instance of AccountAddressEditPanel and AccountAddressListPanel which it will manage. For a
  78. parameter like Addresses/2 it will go directly to the edit panel for that address but signalling the sub
  79. module. By default, the sub modules will show a list page if given no parameters. Each sub-module is
  80. a Page request, the actions within each of these are ajax calls.
  81. The default Account modules managed by the AccountManagerModule are:
  82. - AccountAddressesModule : addresses viewing and management
  83. - AccountOrdersModule : orders viewing and management
  84. - AccountSettingsModule: contains the following
  85. - AccountInfoModule : to change email address, avatar or personal name.
  86. - AccountPasswordModule : change password and username
  87. - AccountProfileModule : public profile information
  88. </Account Management>
  89. <Ecommerce>
  90. Objects:
  91. - Order
  92. - Product
  93. - Shopping cart
  94. - Payment method
  95. - Shipping method
  96. Actors:
  97. - Customer
  98. - Second party payment processor
  99. - Shipping party
  100. - Employees
  101. Events:
  102. - Browse products
  103. initially this means the user is looking at their designs in the account section
  104. the designs have an "add to cart" button possibly with a qty field next to it.
  105. * do we offer this on the line item list or only individual item displays?
  106. - Select products
  107. customer triggers an "add to cart" action, parameters are design id and qty
  108. * if no cart exists, create cart and insert into database. (???) or save as object with session or
  109. account id ..
  110. * add items to association table for the cart (shopping_cart_items)
  111. > if it is a pcb_design, select design from pcb_designs
  112. - if design.product_id == Null, create a product, set design.product_id;
  113. else simply add to association table
  114. - check out process
  115. - Select payment method
  116. - Select Shipping method
  117. - Validate payment
  118. - Record transaction
  119. Architecture:
  120. Orders, Products, Customers. etc. are all ORM objects and the data is managed in the
  121. database. These are dealt with in other parts of the documentation.
  122. There are two main parts of the interactive part of the ecommerce extension: the shopping cart and the
  123. checkout process. The third part is passive display of products in lists or individually, ie. browsing.
  124. ************************
  125. Shopping cart: (Module/View)
  126. The shopping cart is implemented as a module that is similar to the Login Module, it has a small content
  127. block view which is visible if a the viewer is logged in, and a page for viewing and modifying the cart contents.
  128. The contents are displayed in short form in the module and in detail on the ShoppingCart page. The shopping
  129. cart page is configured in the database to have the ShoppingCartView as the primary module in the main block
  130. of the page (usually CenterPanel). The items in the ShoppingCartView and the ShoppingCartMiniView are linked
  131. to product views. The ShoppingCartView is displayed when a user clicks on the "View Cart"
  132. button in the mini view. This is actually implemented as a redirect to the ShoppingCart page where the
  133. ShoppingCartView is the central module.
  134. ************************
  135. CheckOut: (Module - to be implemented, similar to Account Manager but with only two panels)
  136. The checkout process occurs on a page. It contains a central management module: CheckOut. This manages the
  137. Items display, the Address selection, the Payment module and the Shipping module.
  138. There are two panels involved CheckOutEditModule and CheckOutReviewModule, The first is for displaying
  139. the list of items, shipping and billing addresses and a selection of shipping methods. All of these may be modified
  140. on this panel.
  141. On completion of selections of address, shipping method, etc, the CheckOutReviewModule is shown where
  142. one can review the details of the order, select payment option and complete the purchase, or return to modify
  143. the details on the previous panel. These are not actual page loads, but two separate panels connected to the main
  144. Checkout Module which is the central module of the CheckOut page.
  145. Basic Logic:
  146. CheckOut module loads:
  147. * CheckOutEditModule - panel for stage 1, containing item list, addresses w/editting and shipping
  148. method selection
  149. This loads:
  150. - CheckOutItemListModule - modifiable list of items
  151. - AddressViews - shipping and billing, with button to edit each. clicking the edit button hides
  152. the main panel and shows an AddressEditPanel
  153. - Radiolist for shipping options
  154. * CheckOutReviewModule - panel for stage 2, display of item list, totals, addresses, and selected
  155. shipping method followed by payment method selection at the bottom and a "Finish" button.
  156. This loads:
  157. - passive display of items, totals, addresses and shipping method selected
  158. - PaymentModule
  159. gets a list of methods, creates PaymentMethodViews for each with an action
  160. associated that will trigger the appropriate PaymentAction ..
  161. *CheckOutConfirmationModule - merely confirms the order after payment
  162. The Payment and Shipping modules manage the loading and placement of PaymentMethods and
  163. ShippingMethods (respectively). They also serve as the interface to the data obtained my the active or selected
  164. method.
  165. The ShippingModule gets a list of active modules from the shipping_method table. For each, it gets a
  166. RateCalculator appropriate to the method from a "factory" method in the ShippingMethod class. Then it creates a
  167. radio button for the method and pushes it onto an array of radio buttons that are rendered in the template. Each
  168. button has an action to reset the SelectedMethod property in the ShippingModule.
  169. The PaymentModule is slightly more complex. PaymentMethod is also an ORM class from the payment_method
  170. table, and it also provides a factory method to return a PaymentAction based on the service provider and the
  171. service type (like ShippingModule). However, rather than rendering these directly (as the requirements for each
  172. differ), PaymentModule creates a PaymentAction for each method. This will be a subclass of
  173. PaymentActionBase for the method, eg AuthorizeNetAction, or PayPalIPNAction. The PaymentAction
  174. is also subclassed for the provider and service in a similar way and the naming convention is the same.
  175. PaymentModule - controller block view
  176. creates:
  177. PaymentMethod - ORM model
  178. creates:
  179. PaymentAction - collect information and/or connect to provider to perform actual transaction
  180. |_
  181. | \PayPalWPSAction
  182. |_
  183. | \AuthorizeNetAction
  184. |_
  185. \etc ..
  186. Basic Workflow:
  187. 1. In PaymentModule
  188. 1.1 a list of active PaymentMethods is obtained from the database
  189. 1.2 an array of QRadioButtons is created, each has the PaymentMethod->Id as an action parameter
  190. 1.3 fields for credit card input are created. These are rendered below the payment options
  191. 1.4. PaymentAction for the method is created by PaymentModule::btn_Purchase_Click
  192. when the user clicks "Purchase" based on the class_name field in payment_methods
  193. - PaymentAction initilizes some defaults and other values are set according to the
  194. method's requirements - this is configuration data and the PaymentAction is responsible
  195. for knowing what to set.
  196. - PaymentAction->PreProcess is called
  197. - PaymentAction->Process is called
  198. - PaymentAction->PostProcess is called
  199. PaymentActions:
  200. PayPal Express Checkout
  201. This is non-standard due to the requirements from PayPal - the PaymentActionView offers this as an option on the
  202. review panel which will set the method and there is a "Check Out with PayPal" button at the bottom of the Edit
  203. panel as well. Clicking the button will set the selected payment method _and_ trigger the PaymentAction while
  204. selecting the option will only set the payment method, leaving the action to be triggered by the "Pay" button on
  205. the review Panel.
  206. ************************
  207. Browsing Products:
  208. Product Display (ListModule)
  209. ProductDisplayModule extends the ListModuleBase in the same manner as the Account address module - it
  210. manages an ajax controlled set of panels for showing a list of products or a single product. The module
  211. parses the page parameters (derived from the URL, see the notes above for the Account manager module),
  212. ************************
  213. Order history:
  214. Order viewing is handled as a ListModule in the Account Manager module - see the Address manager module
  215. above and Product display.
  216. =========================================
  217. </Ecommerce>
  218. <Lost Password>
  219. The LostPasswordModule is displayed on the Page "LostPassword", it performs the following actions:
  220. 1. Prompts the user for either username or email associated with the account.
  221. 2. Generates a new random password for the account
  222. The user must input either the email for the account or the username
  223. 3. Sets the temporary password in the account and sets the flag onetime_password to true.
  224. 4. Emails the password to the user
  225. The user can then use this to log in - the LoginModule checks the onetime_password flag; if set it will redirect the
  226. user to the account password settings module. The following are the possible state changes:
  227. on signup
  228. set onetime_password = false
  229. set valid_password = true.
  230. on lost password module resets password,
  231. set onetime_password = true
  232. set valid_password = true
  233. on login
  234. if valid_password == false
  235. then
  236. show error page with link to "forgot password"
  237. if onetime_password == true
  238. then
  239. redirect to AccountHome/Settings/Password
  240. set valid_password = false
  241. on user resets password,
  242. set onetime_password = false
  243. set valid_password = true
  244. </Lost Password>