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.

438 lines
18 KiB

12 years ago
  1. <?php
  2. /**
  3. * Include to load Quasi which extends QApplication class, configurations and the QCodo framework
  4. * and local Quasi configurations which can be set in core/quasi_config.php.
  5. * Note: This assumes that this file and Quasi.class.php are in the same directory - adjust as needed.
  6. * Note also that (at least under linux ..) this works even if a symlink is what is actually accessed.
  7. */
  8. require(dirname(__FILE__) . '/Quasi.class.php');
  9. // if you want to restrict access uncomment this:
  10. // Quasi::CheckRemoteAdmin();
  11. /// PageView takes over after IndexPage is finished ..
  12. require( __QUASI_CORE_CLASSES__ . "/PageView.class.php");
  13. /**
  14. * IndexPage is the central controller class of Quasi - it handles all URL
  15. * requests and loads the PageView for the request. It is essentially the
  16. * "One Form to rule them all" - the entire CMS is derived from access to
  17. * this class. It should be named index.php with the corresponding template
  18. * index.tpl.php and placed in the directory configured as __QUASI_ROOT__ in
  19. * Quasi.class.php (required above). The page view to load is determined by
  20. * the section of the request URL immediately following index.php - it
  21. * defaults to "Home" if the string is empty.
  22. *
  23. * See the class PageView for subsequent control logic - PageView loads the
  24. * ContentBlockViews which then handle MenuViews, ContentItemViews and
  25. * Modules associated with each ContentBlock.
  26. *
  27. * NOTE: Possible architectural change: Move static globals and some init
  28. * things from here and some other init and configuration things from
  29. * QApplication to a Class Quasi (extends QApplication). The main idea
  30. * is to get all initialization and configurations along with all
  31. * subsequent global data in one place and also decouple Quasi from
  32. * the QCodo tree so that we can drop into place without disturbing
  33. * anything, allowing for updates on both and a simpler installation.
  34. * update: partially done, see class Quasi
  35. *
  36. *@author Erik Winn <erikwinnmail@yahoo.com>
  37. *
  38. *
  39. * $Id: index.php 513 2009-03-12 22:03:03Z erikwinn $
  40. *@version 0.1
  41. *
  42. *@copyright (C) 2008 by Erik Winn *@license GPL v.2
  43. This program is free software; you can redistribute it and/or modify
  44. it under the terms of the GNU General Public License as published by
  45. the Free Software Foundation; either version 2 of the License, or
  46. (at your option) any later version.
  47. This program is distributed in the hope that it will be useful,
  48. but WITHOUT ANY WARRANTY; without even the implied warranty of
  49. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  50. GNU General Public License for more details.
  51. You should have received a copy of the GNU General Public License
  52. along with this program; if not, write to the Free Software
  53. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
  54. *
  55. *@package Quasi
  56. *@subpackage Classes
  57. */
  58. class IndexPage extends QForm
  59. {
  60. /**
  61. * @var boolean blnAjaxOk - if true we use AJAX, if not we issue server calls
  62. */
  63. public static $blnAjaxOk = false;
  64. /**
  65. * MainWindow provides a point of reference for Quasi Modules to access Control arrays in the
  66. * managing QForm. (currently unused .. may be removed)
  67. * @var MainWindow MainWindow - the global reference to the index QForm object
  68. */
  69. public static $MainWindow;
  70. /**
  71. * NOTE: any account always has a single shopping cart, it will retain any items in it
  72. * until they either check out or remove them.
  73. * @var ShoppingCart objShoppingCart - self explanatory ..
  74. */
  75. public static $objShoppingCart;
  76. /**
  77. * @var Account objAccount - the currently logged in account, null if not logged in
  78. */
  79. public static $objAccount;
  80. /**
  81. * @var string strPageRequest - the name of the current page, Page object is loaded from the database
  82. */
  83. public static $strPageRequest;
  84. /**
  85. * This string contains parameters that may be parsed by modules on the Page, eg. after "Products"
  86. * we might have nothing (""), activating the product list module or "234" activating the product view for that
  87. * product Id. The original request was http://www.mysite.com/index.php/Products/234 - "Products" is stored
  88. * in PageRequest, 234 is stored here in PageParameters.
  89. * @var string strPageParameters - everything after the Page name, ie parameters for the Page
  90. */
  91. public static $strPageParameters;
  92. /**
  93. * @var array aryStyleSheets - an array of CSS stylesheets to be inserted into the HEAD for the PageView
  94. */
  95. protected $aryStyleSheets;
  96. /**
  97. * @var array aryJavaScripts - an array of JavaScript files to be inserted into the HEAD for the PageView
  98. */
  99. protected $aryJavaScripts;
  100. /**
  101. * @var string strPreferedStyleSheet - CSS stylesheet to be flagged as prefered into the HEAD for the PageView
  102. */
  103. protected $strPreferedStyleSheet;
  104. /**
  105. * @var array aryCssDirectories - relative paths to the possible directories containing stylesheets
  106. */
  107. protected $aryCssDirectories = array(
  108. __QUASI_CORE_CSS__,
  109. __QUASI_CONTRIB_CSS__,
  110. __QUASI_LOCAL_CSS__,
  111. );
  112. /**
  113. * @var array aryJavaScriptDirectories - absolute paths to the possible directories containing javascript files
  114. */
  115. protected $aryJavaScriptDirectories = array(
  116. __QUASI_LOCAL_JS__,
  117. __QUASI_CONTRIB_JS__,
  118. __QUASI_CORE_JS__,
  119. );
  120. /**
  121. * @var array aryModuleDirectories - absolute paths to the possible directories containing modules
  122. */
  123. protected $aryModuleDirectories = array(
  124. __QUASI_LOCAL_MODULES__,
  125. __QUASI_CONTRIB_MODULES__,
  126. __QUASI_CORE_MODULES__,
  127. );
  128. /**
  129. * @var string defaultStyleSheet - default CSS stylesheet
  130. */
  131. protected $defaultStyleSheet = 'quasi.css';
  132. /**
  133. * @var Page objPage - the Page object from the database for this request
  134. */
  135. protected $objPage;
  136. /**
  137. * @var PageView objPageView - the PageView display object, renders ContentBlocks
  138. */
  139. protected $objPageView;
  140. /**
  141. * This array is initilized by the module loader in ContentBlockView
  142. * @todo - figure out how to make this work. (Note: i suspect a clone in QForm may be breaking this ..)
  143. *@var array ActiveModules - an array of references to modules which have been loaded.
  144. */
  145. public $ActiveModules;
  146. //experimental thinking - ignore at will ..
  147. protected function __construct()
  148. {
  149. parent::__construct();
  150. self::$MainWindow = $this;
  151. }
  152. /**
  153. * This function runs on all requests - full POST, URL links, or Ajax requests, ie. always.
  154. * Form_Create below runs only on page loads - ie. not for Ajax calls.
  155. * Thus, we set the important global data up here: request string, login state, shopping cart.
  156. * This ensures that these are set when an action returns the form state.
  157. */
  158. protected function Form_Run()
  159. {
  160. //Ok, figure out what page we are
  161. $aryRequest = explode('/', Quasi::$PathInfo);
  162. //remove scriptname (index.php)
  163. array_shift($aryRequest);
  164. //store page name
  165. self::$strPageRequest = array_shift($aryRequest);
  166. //store extra parameters
  167. self::$strPageParameters = implode( '/', $aryRequest);
  168. //Then check / set login status
  169. if( ! isset($_SESSION['AccountLogin']) )
  170. {
  171. //timed out .. redirect home (avoid qcodo exception)
  172. if(self::$objAccount instanceof Account)
  173. {
  174. self::$objAccount = null;
  175. Quasi::Redirect(__QUASI_SUBDIRECTORY__ . '/index.php/Home');
  176. }
  177. self::$objAccount = null;
  178. }
  179. else
  180. {
  181. self::$objAccount = unserialize( $_SESSION['AccountLogin'] );
  182. if( ! self::$objAccount instanceof Account )
  183. {
  184. unset($_SESSION['AccountLogin']);
  185. self::$objAccount = null;
  186. Quasi::Redirect(__QUASI_SUBDIRECTORY__ . '/index.php/Home');
  187. }
  188. }
  189. ///@todo - only set up Shopping cart if ecommerce is enabled ..
  190. // set up the user's Shopping cart if the user is logged in
  191. if(self::$objAccount instanceof Account && ! self::$objShoppingCart instanceof ShoppingCart)
  192. {
  193. $objShoppingCart = ShoppingCart::LoadByAccountId(self::$objAccount->Id);
  194. // still no cart? ok, they have just signed up, make a new cart for them
  195. if(!$objShoppingCart)
  196. {
  197. $objShoppingCart = new ShoppingCart();
  198. $objShoppingCart->AccountId = self::$objAccount->Id;
  199. $objShoppingCart->Save();
  200. }
  201. self::$objShoppingCart = $objShoppingCart;
  202. }
  203. // turn off AJAX for known problem browsers ..
  204. if( Quasi::IsBrowser( QBrowserType::InternetExplorer_6_0 )
  205. || Quasi::IsBrowser( QBrowserType::Safari )
  206. || Quasi::IsBrowser( QBrowserType::Opera ))
  207. self::$blnAjaxOk = false;
  208. else
  209. self::$blnAjaxOk = true;
  210. }
  211. protected function Form_Create()
  212. {
  213. //redirect to include index.php and start out with our url scheme
  214. if( empty(Quasi::$ScriptName ) )
  215. Quasi::Redirect(__QUASI_SUBDIRECTORY__ . '/index.php/Home');
  216. elseif( empty(self::$strPageRequest) )
  217. self::$strPageRequest = "Home";
  218. // Now get the Page row from the database ..
  219. $this->objPage = Page::LoadByName(self::$strPageRequest);
  220. // @todo implement 404 page not found .. for now, we just go home.
  221. if(!$this->objPage )
  222. {
  223. self::$strPageRequest = "Home";
  224. $this->objPage = Page::LoadByName(self::$strPageRequest);
  225. }
  226. if( $this->objPage)
  227. {
  228. // $this->loadModules();
  229. $this->objPageView = new PageView( $this, $this->objPage );
  230. $this->aryStyleSheets = StyleSheet::LoadArrayByPage( $this->objPage->Id );
  231. $this->strPreferedStyleSheet = $this->aryStyleSheets[0];
  232. }
  233. else
  234. $this->strPreferedStyleSheet = $this->defaultStyleSheet;
  235. /**
  236. * Find stylesheets - we look first in core assets, then contrib and
  237. * finally cascade to local. If none is found we fly naked just to be obvious ..
  238. */
  239. if(is_array($this->aryStyleSheets) )
  240. foreach($this->aryStyleSheets as $filename)
  241. {
  242. foreach( $this->aryCssDirectories as $basedir )
  243. {
  244. $strUrl = $basedir . '/' . $filename;
  245. if(file_exists(__WWWROOT__ . $strUrl))
  246. $this->aryStyleSheets[] = $strUrl;
  247. }
  248. }
  249. $this->aryJavaScripts = JavaScript::LoadArrayByPage( $this->objPage->Id );
  250. if(is_array($this->aryJavaScripts) )
  251. foreach($this->aryJavaScripts as $objJavaScript)
  252. {
  253. foreach( $this->aryJavaScriptDirectories as $basedir )
  254. {
  255. $strUrl = $basedir . '/' . $objJavaScript->Filename;
  256. if(file_exists(__WWWROOT__ . $strUrl))
  257. {
  258. $this->aryJavaScripts[] = $strUrl;
  259. break;
  260. }
  261. }
  262. }
  263. $this->objDefaultWaitIcon = new QWaitIcon($this);
  264. }
  265. /**
  266. * This Form_Validate event handler allows you to specify any custom Form Validation rules.
  267. * It will also Blink() on all invalid controls, as well as Focus() on the top-most invalid control.
  268. * NOTE: Currently disabled to avoid conflicts with validation in modules
  269. * @todo work out what to do about this, since the whole CMS is essentially one form we
  270. * need a more coherant system for event and signal handling ..
  271. */
  272. protected function Form_Validate()
  273. {
  274. // By default, we report that Custom Validations passed
  275. $blnToReturn = true;
  276. /*
  277. $blnFocused = false;
  278. foreach ($this->GetErrorControls() as $objControl) {
  279. // Set Focus to the top-most invalid control
  280. if (!$blnFocused) {
  281. $objControl->Focus();
  282. $blnFocused = true;
  283. }
  284. // Blink on ALL invalid controls
  285. $objControl->Blink();
  286. }
  287. */
  288. return $blnToReturn;
  289. }
  290. protected function handleUrl()
  291. {
  292. $aryRequest = explode('/', self::$strPageRequest);
  293. self::$strPageRequest = array_shift($aryRequest);
  294. self::$strPageParameters = implode( '/', $aryRequest);
  295. }
  296. /**
  297. * This function returns a reference to an active module if it is in the list. Otherwise, it returns null
  298. * You must pass the name of the module to return.
  299. * WARNING: BROKEN - do not use.
  300. * @todo - figure out how to make this work. (Note: i suspect a clone in QForm may be breaking this ..)
  301. *
  302. *@param string strModuleName
  303. * @return object SomeModule or null
  304. */
  305. public function GetActiveModule($strModuleName)
  306. {
  307. if( is_array($this->ActiveModules))
  308. foreach( $this->ActiveModules as $objModuleView )
  309. {
  310. $strTestName = get_class( $objModuleView );
  311. if( $strTestName == $strModuleName )
  312. return $objModuleView;
  313. }
  314. return null;
  315. }
  316. public function AddActiveModule($objModule)
  317. {
  318. $this->ActiveModules[] = $objModule;
  319. }
  320. /**
  321. * Loads any modules associated with content blocks on the requested page.
  322. * Note that the order of loading is local, then contrib, then core. This only runs
  323. * on the first form access (including redirects to ourself ) - might speed things
  324. * up a bit, otherwise Quasi::Autoload will take care of loading.
  325. * @todo test to see which is faster - currently unused.
  326. */
  327. protected function loadModules()
  328. {
  329. $aryContentBlocks = $this->objPage->GetContentBlockArray();
  330. foreach($aryContentBlocks as $objContentBlock)
  331. {
  332. $aryModules = $objContentBlock->GetModuleArray();
  333. foreach($aryModules as $objModule)
  334. {
  335. $strClassFileName = $objModule->ClassName . '.class.php';
  336. foreach( $this->aryModuleDirectories as $strDir )
  337. {
  338. $strIncludeUri = $strDir . '/' . $strClassFileName;
  339. if( file_exists($strIncludeUri) )
  340. {
  341. require_once($strIncludeUri);
  342. break;
  343. }
  344. }
  345. }
  346. }
  347. }
  348. //Note - these are unused currently, but left as a reminder for possible future
  349. // architectural change - essentially we could make almost anything a panel
  350. // (anywhere?) with ajax/server calls for display management...
  351. public function HidePanel(QPanel $objPanel)
  352. {
  353. if( true === $objPanel->Visible)
  354. $objPanel->Visible = false;
  355. }
  356. public function ShowPanel(QPanel $objPanel = null)
  357. {
  358. if ($objPanel)
  359. {
  360. $objPanel->SetParentControl($this);
  361. if( false === $objPanel->Visible)
  362. $objPanel->Visible = true;
  363. }
  364. }
  365. public function __get($strName)
  366. {
  367. switch ($strName)
  368. {
  369. case 'PageTitle':
  370. return $this->objPage->Title;
  371. case 'StyleSheetPath':
  372. return $this->strStyleSheetPath;
  373. case 'PreferedStyleSheet':
  374. return $this->strPreferedStyleSheet;
  375. case 'PageRequest':
  376. return self::$strPageRequest ;
  377. default:
  378. try {
  379. return parent::__get($strName);
  380. } catch (QCallerException $objExc) {
  381. $objExc->IncrementOffset();
  382. throw $objExc;
  383. }
  384. }
  385. }
  386. public function __set($strName, $mixValue)
  387. {
  388. switch ($strName)
  389. {
  390. case 'PreferedStyleSheet':
  391. try {
  392. return ($this->strPreferedStyleSheet = QType::Cast($mixValue, QType::String));
  393. } catch (QInvalidCastException $objExc) {
  394. $objExc->IncrementOffset();
  395. throw $objExc;
  396. }
  397. default:
  398. try {
  399. return (parent::__set($strName, $mixValue));
  400. } catch (QCallerException $objExc) {
  401. $objExc->IncrementOffset();
  402. throw $objExc;
  403. }
  404. }
  405. }
  406. }
  407. IndexPage::Run('IndexPage', "index.tpl.php");
  408. ?>