PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/library/Adapto/Controller.php

http://github.com/egeniq/adapto
PHP | 815 lines | 500 code | 68 blank | 247 comment | 66 complexity | 8bd643234f7e290c2a73db84e3eae4ae MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Adapto Toolkit.
  4. * Detailed copyright and licensing information can be found
  5. * in the doc/COPYRIGHT and doc/LICENSE files which should be
  6. * included in the distribution.
  7. *
  8. * @package adapto
  9. *
  10. * @copyright (c)2000-2004 Ibuildings.nl BV
  11. * @license http://www.achievo.org/atk/licensing ATK Open Source License
  12. *
  13. */
  14. /**
  15. * The Adapto_Controller class
  16. *
  17. * @author Maurice Maas <maurice@ibuildings.nl>
  18. * @package adapto
  19. * @todo Make this class a real singleton.
  20. */
  21. class Adapto_Controller
  22. {
  23. /**
  24. * The name of the wizard.
  25. * @access protected
  26. * @var String
  27. */
  28. public $m_name; // defaulted to public
  29. /**
  30. * The module of the wizard.
  31. * @access protected
  32. * @var String
  33. */
  34. public $m_module_name; // defaulted to public
  35. /**
  36. * Reference to the instance of currently selected atkEntity
  37. *
  38. * @var unknown_type
  39. */
  40. public $m_entity = NULL; // defaulted to public
  41. /**
  42. * The postvars in this pageload
  43. *
  44. * @var array Key/value
  45. */
  46. public $m_postvars = NULL; // defaulted to public
  47. /**
  48. * The file to use when creating url's
  49. *
  50. * @var string filename
  51. */
  52. public $m_php_file = ""; // defaulted to public
  53. /**
  54. * By this property is determined if the output of the
  55. * handleRequest method should be returned as a string
  56. * or the output should be outputted by atkOutput.
  57. *
  58. * @var unknown_type
  59. */
  60. public $m_return_output = false; // defaulted to public
  61. /**
  62. * Key/value Array containing which are be send als post or get vars
  63. * @access private
  64. * @var Array
  65. */
  66. public $m_hidden_vars = array(); // defaulted to public
  67. /**
  68. * Constructor of Adapto_Controller
  69. *
  70. * @return Adapto_Controller object
  71. */
  72. public function __construct()
  73. {
  74. global $g_sessionManager;
  75. if (is_object($g_sessionManager)) {
  76. $atkControllerClass = $g_sessionManager->stackVar("atkcontroller");
  77. //Its not so nice to use the getEntityModule and getEntityType functions,
  78. //because the name suggests they work with atkEntitys. But they also do
  79. //the job when using other class names.
  80. $this->m_name = getEntityType($atkControllerClass);
  81. $this->m_module_name = getEntityModule($atkControllerClass);
  82. }
  83. }
  84. /**
  85. * Create instance of controller (determined by class variable) if not yet created, return instance of atkcontroller
  86. *
  87. * @access private
  88. * @param string $class
  89. * @param boolean $replace
  90. * @return instance of controller
  91. */
  92. function &_instance($class = "", $replace = false)
  93. {
  94. static $s_object = NULL;
  95. if (!is_object($s_object) || $replace) {
  96. global $Adapto_VARS;
  97. if (empty($class) && isset($Adapto_VARS['atkcontroller']))
  98. $class = $Adapto_VARS['atkcontroller'];
  99. if (empty($class))
  100. $class = "atk.atkcontroller";
  101. //We save the controller in stack, so the controller constructor
  102. //can store the Controller name and module. It is also saved for other
  103. //atk levels if we move down the stack.
  104. global $g_sessionManager;
  105. if (is_object($g_sessionManager)) {
  106. $g_sessionManager->stackVar("atkcontroller", $class);
  107. }
  108. $s_object = Adapto_ClassLoader::create($class);
  109. }
  110. return $s_object;
  111. }
  112. /**
  113. * Return the one and only instance of the class
  114. *
  115. * @return Adapto_Controller
  116. */
  117. function &getInstance()
  118. {
  119. $object = &atkcontroller::_instance();
  120. return $object;
  121. }
  122. /**
  123. * Return the one and only instance of the class
  124. *
  125. * @param string $controller The class of the controller to instanciate
  126. * @return object
  127. */
  128. function &createInstance($controller)
  129. {
  130. Adapto_Util_Debugger::debug("atkcontroller::createInstance() " . $controller);
  131. //First check if another controller is active. If so make sure this
  132. //controller will use atkOutput to return output
  133. $currentController = Adapto_Controller::getInstance();
  134. if (is_object($currentController))
  135. $currentController->setReturnOutput(true);
  136. //Now create new controller
  137. $controller = Adapto_Controller::_instance($controller, true);
  138. return $controller;
  139. }
  140. /**
  141. * This is the wrapper method for all http requests on an entity.
  142. *
  143. * The method looks at the atkaction from the postvars and determines what
  144. * should be done. If possible, it instantiates actionHandlers for
  145. * handling the actual action.
  146. *
  147. * @param array $postvars The request variables for the entity.
  148. * @param string $flags Render flags (see class atkPage).
  149. *
  150. */
  151. function handleRequest($postvars, $flags = NULL)
  152. {
  153. // we set the m_postvars variable of the controller for backwards compatibility reasons (when using $obj->dispatch in the dispatch.php)
  154. $this->m_postvars = $postvars;
  155. $entity = &$this->getEntity();
  156. $entity->m_postvars = $postvars;
  157. if (!is_object($entity) || !method_exists($entity, 'getUi'))
  158. return "";
  159. $page = &$entity->getPage();
  160. // backwards compatibility mode
  161. if ($flags == NULL) {
  162. $flags = array_key_exists("atkpartial", $postvars) ? HTML_PARTIAL : HTML_STRICT;
  163. } elseif (is_bool($flags)) {
  164. $flags = $flags ? HTML_STRICT : HTML_HEADER | HTML_DOCTYPE;
  165. }
  166. // Use invoke to be backwards compatible with overrides
  167. // of loadDispatchPage in atkentity.
  168. $this->invoke("loadDispatchPage", $postvars);
  169. $screen = '';
  170. if (!$page->isEmpty() || hasFlag($flags, HTML_PARTIAL)) // Only output an html output if there is anything to output.
  171. {
  172. $screen = $page->render(null, $flags);
  173. }
  174. if (!$this->m_return_output) {
  175. $output = &atkOutput::getInstance();
  176. $output->output($screen);
  177. }
  178. // This is the end of all things for this page..
  179. // so we clean up some resources..
  180. $db = &$entity->getDb();
  181. if (is_object($db))
  182. $db->disconnect();
  183. Adapto_Util_Debugger::debug("disconnected from the database");
  184. if ($this->m_return_output) {
  185. return $screen;
  186. }
  187. return "";
  188. }
  189. /**
  190. * Return the html title for the content frame. Default we show entity name and action.
  191. */
  192. protected function getHtmlTitle()
  193. {
  194. $entity = &$this->getEntity();
  195. $ui = &$entity->getUi();
  196. return atktext('app_shorttitle') . " - " . $ui->title($entity->m_module, $entity->m_type, $entity->m_postvars['atkaction']);
  197. }
  198. /**
  199. * This method is a wrapper for calling the entity dispatch function
  200. * Therefore each entity can define it's own dispatch function
  201. * The default dispatch function of the atkEntity will call the handleRequest function of the controller
  202. *
  203. * @param array $postvars
  204. * @param integer $flags
  205. */
  206. function dispatch($postvars, $flags = NULL)
  207. {
  208. $this->m_postvars = $postvars;
  209. $entity = &$this->getEntity();
  210. return $entity->dispatch($postvars, $flags);
  211. }
  212. /**
  213. * Set m_entity variable of this class
  214. *
  215. * @param object $entity
  216. */
  217. function setEntity(&$entity)
  218. {
  219. $this->m_entity = &$entity;
  220. }
  221. /**
  222. * Get m_entity variable or if not set make instance of atkEntity class (determined by using the postvars)
  223. *
  224. * @return reference to atkentity
  225. */
  226. function &getEntity()
  227. {
  228. if (is_object($this->m_entity)) {
  229. return $this->m_entity;
  230. } else {
  231. //if the object not yet exists, try to create it
  232. $fullclassname = $this->m_postvars["atkentitytype"];
  233. if (isset($fullclassname) && $fullclassname != null) {
  234. $this->m_entity = &getEntity($fullclassname);
  235. if (is_object($this->m_entity)) {
  236. return $this->m_entity;
  237. } else {
  238. global $Adapto_VARS;
  239. throw new Adapto_Exception("No object '" . $Adapto_VARS["atkentitytype"] . "' created!!?!");
  240. }
  241. }
  242. }
  243. $res = NULL;
  244. return $res; // prevent notice
  245. }
  246. /**
  247. * Does the actual loading of the dispatch page
  248. * And adds it to the page for the dispatch() method to render.
  249. * @param array $postvars The request variables for the entity.
  250. */
  251. function loadDispatchPage($postvars)
  252. {
  253. $this->m_postvars = $postvars;
  254. $entity = &$this->getEntity();
  255. if (!is_object($entity))
  256. return;
  257. $entity->m_postvars = $postvars;
  258. $entity->m_action = $postvars['atkaction'];
  259. if (isset($postvars["atkpartial"])) {
  260. $entity->m_partial = $postvars["atkpartial"];
  261. }
  262. $page = &$entity->getPage();
  263. $page->setTitle(atktext('app_shorttitle') . " - " . $this->getUi()->title($entity->m_module, $entity->m_type, $entity->m_action));
  264. if ($entity->allowed($entity->m_action)) {
  265. $secMgr = &atkGetSecurityManager();
  266. $secMgr->logAction($entity->m_type, $entity->m_action);
  267. $entity->callHandler($entity->m_action);
  268. if (isset($entity->m_postvars["atkselector"]) && is_array($entity->m_postvars["atkselector"])) {
  269. $atkSelectorDecoded = array();
  270. foreach ($entity->m_postvars["atkselector"] as $rowIndex => $selector) {
  271. list($selector, $pk) = explode("=", $selector);
  272. $atkSelectorDecoded[] = $pk;
  273. $id = implode(',', $atkSelectorDecoded);
  274. }
  275. } else {
  276. list($selector, $id) = explode("=", atkarraynvl($entity->m_postvars, "atkselector", "="));
  277. }
  278. $page->register_hiddenvars(array("atkentitytype" => $entity->m_module . "." . $entity->m_type, "atkselector" => str_replace("'", "", $id)));
  279. } else {
  280. $page->addContent($this->accessDeniedPage());
  281. }
  282. }
  283. /**
  284. * Render a generic access denied page.
  285. *
  286. * @return String A complete html page with generic access denied message.
  287. */
  288. function accessDeniedPage()
  289. {
  290. $entity = &$this->getEntity();
  291. $content = "<br><br>" . atktext("error_entity_action_access_denied", "", $entity->m_type) . "<br><br><br>";
  292. // Add a cancel button to an error page if it is a dialog.
  293. if ($entity->m_partial == 'dialog')
  294. $content .= $this->getDialogButton('cancel', 'close');
  295. return $this->genericPage(atktext('access_denied'), $content);
  296. }
  297. /**
  298. * Render a generic page, with a box, title, stacktrace etc.
  299. * @param String $title The pagetitle and if $content is a string, also
  300. * the boxtitle.
  301. * @param mixed $content The content to display on the page. This can be:
  302. * - A string which will be the content of a single
  303. * box on the page.
  304. * - An associative array of $boxtitle=>$boxcontent
  305. * pairs. Each pair will be rendered as a seperate
  306. * box.
  307. * @return String A complete html page with the desired content.
  308. */
  309. function genericPage($title, $content)
  310. {
  311. $entity = &$this->getEntity();
  312. $ui = &$entity->getUi();
  313. $entity->addStyle("style.css");
  314. if (!is_array($content))
  315. $content = array($title => $content);
  316. $blocks = array();
  317. foreach ($content as $itemtitle => $itemcontent) {
  318. if ($entity->m_partial == 'dialog')
  319. $blocks[] = $ui->renderDialog(array("title" => $itemtitle, "content" => $itemcontent));
  320. else
  321. $blocks[] = $ui->renderBox(array("title" => $itemtitle, "content" => $itemcontent), 'dispatch');
  322. }
  323. /**
  324. * @todo Don't use renderActionPage here because it tries to determine
  325. * it's own title based on the title which is passed as action.
  326. * Instead use something like the commented line below:
  327. */
  328. //return $ui->render("actionpage.tpl", array("blocks"=>$blocks, "title"=>$title));
  329. return $this->renderActionPage($title, $blocks);
  330. }
  331. /**
  332. * Render a generic action.
  333. *
  334. * Renders actionpage.tpl for the desired action. This includes the
  335. * given block(s) and a pagetrial, but not a box.
  336. * @param String $action The action for which the page is rendered.
  337. * @param mixed $blocks Pieces of html content to be rendered. Can be a
  338. * single string with content, or an array with
  339. * multiple content blocks.
  340. * @return String Piece of HTML containing the given blocks and a pagetrail.
  341. */
  342. function renderActionPage($action, $blocks = array())
  343. {
  344. if (!is_array($blocks)) {
  345. $blocks = ($blocks == "" ? array() : array($blocks));
  346. }
  347. $entity = &$this->getEntity();
  348. $ui = &$entity->getUi();
  349. // todo: overridable action templates
  350. return $ui->render("actionpage.tpl", array("blocks" => $blocks, "title" => $this->actionPageTitle()));
  351. }
  352. /**
  353. * Return the title to be show on top of an Action Page
  354. *
  355. * @return string The title
  356. */
  357. function actionPageTitle()
  358. {
  359. $entity = &$this->getEntity();
  360. $ui = &$entity->getUi();
  361. return $ui->title($entity->m_module, $entity->m_type);
  362. }
  363. /**
  364. * Determine the url for the feedbackpage.
  365. *
  366. * Output is dependent on the feedback configuration. If feedback is not
  367. * enabled for the action, this method returns an empty string, so the
  368. * result of this method can be passed directly to the redirect() method
  369. * after completing the action.
  370. *
  371. * The $record parameter is ignored by the default implementation, but
  372. * derived classes may override this method to perform record-specific
  373. * feedback.
  374. * @param String $action The action that was performed
  375. * @param int $status The status of the action.
  376. * @param array $record The record on which the action was performed.
  377. * @param String $message An optional message to pass to the feedbackpage,
  378. * for example to explain the reason why an action
  379. * failed.
  380. * @param integer $levelskip The number of levels to skip
  381. * @return String The feedback url.
  382. */
  383. function feedbackUrl($action, $status, $record = "", $message = "", $levelskip = null)
  384. {
  385. $entity = &$this->getEntity();
  386. if ((isset($entity->m_feedback[$action]) && hasFlag($entity->m_feedback[$action], $status)) || $status == ACTION_FAILED) {
  387. $vars = array("atkaction" => "feedback", "atkfbaction" => $action, "atkactionstatus" => $status, "atkfbmessage" => $message);
  388. $atkEntityType = $entity->atkEntityType();
  389. $sessionStatus = SESSION_REPLACE;
  390. // The level skip given is based on where we should end up after the
  391. // feedback action is shown to the user. This means that the feedback
  392. // action should be shown one level higher in the stack, hence the -1.
  393. // Default the feedback action is shown on the current level, so in that
  394. // case we have a simple SESSION_REPLACE with a level skip of null.
  395. $levelskip = $levelskip == null ? null : $levelskip - 1;
  396. } else {
  397. // Default we leave atkEntityType empty because the sessionmanager will determine which is de atkEntityType
  398. $vars = array();
  399. $atkEntityType = "";
  400. $sessionStatus = SESSION_BACK;
  401. }
  402. return (session_url($this->dispatchUrl($vars, $atkEntityType), $sessionStatus, $levelskip));
  403. }
  404. /**
  405. * Generate a dispatch menu URL for use with entitys
  406. * and their specific actions.
  407. * @param string $params: A key/value array with extra options for the url
  408. * @param string $atkentitytype The atkentitytype (modulename.entityname)
  409. * @param string $file The php file to use for dispatching, defaults to dispatch.php
  410. * @return string url for the entity with the action
  411. */
  412. function dispatchUrl($params = array(), $atkentitytype = "", $file = "")
  413. {
  414. if (!is_array($params))
  415. $params = array();
  416. $vars = array_merge($params, $this->m_hidden_vars);
  417. if ($file != "")
  418. $phpfile = $file;
  419. else
  420. $phpfile = $this->getPhpFile();
  421. // When $atkentitytype is empty this means that we use the atkentitytype from session
  422. $dispatch_url = dispatch_url($atkentitytype, atkArrayNvl($vars, "atkaction", ""), $vars, $phpfile);
  423. return $dispatch_url;
  424. }
  425. /**
  426. * Returns the form buttons for a certain page.
  427. *
  428. * Can be overridden by derived classes to define custom buttons.
  429. * @param String $mode The action for which the buttons are retrieved.
  430. * @param array $record The record currently displayed/edited in the form.
  431. * This param can be used to define record specific
  432. * buttons.
  433. */
  434. function getFormButtons($mode, $record)
  435. {
  436. $result = array();
  437. $entity = &$this->getEntity();
  438. $page = &$entity->getPage();
  439. $page->register_script(Adapto_Config::getGlobal("atkroot") . "atk/javascript/tools.js");
  440. // edit mode
  441. if ($mode == "edit") {
  442. // if atklevel is 0 or less, we are at the bottom of the session stack,
  443. // which means that 'saveandclose' doesn't close anyway, so we leave out
  444. // the 'saveandclose' and 'cancel' button. Unless, a feedback screen is configured.
  445. if (atkLevel() > 0 || hasFlag(atkArrayNvl($entity->m_feedback, "update", 0), ACTION_SUCCESS)) {
  446. $result[] = $this->getButton('saveandclose', true);
  447. }
  448. $result[] = $this->getButton('save');
  449. if (atkLevel() > 0 || hasFlag(atkArrayNvl($entity->m_feedback, "update", 0), ACTION_SUCCESS)) {
  450. $result[] = $this->getButton('cancel');
  451. }
  452. } elseif ($mode == "add") {
  453. if ($entity->hasFlag(EF_EDITAFTERADD) === true && $entity->allowed('edit')) {
  454. $result[] = $this->getButton('saveandedit', true);
  455. } else {
  456. if ($entity->hasFlag(EF_EDITAFTERADD) === true) {
  457. atkwarning("EF_EDITAFTERADD found but no 'edit' privilege.");
  458. }
  459. $result[] = $this->getButton('saveandclose', true);
  460. }
  461. // if action is admin, we don't show the cancelbutton or the add next button
  462. if ($entity->hasFlag(EF_ADDAFTERADD) && !$entity->hasFlag(EF_EDITAFTERADD))
  463. $result[] = $this->getButton('saveandnext', false);
  464. $result[] = $this->getButton('cancel');
  465. } elseif ($mode == "view") {
  466. if (atkLevel() > 0)
  467. $result[] = $this->getButton('back');
  468. // if appropriate, display an edit button.
  469. if (!$entity->hasFlag(EF_NO_EDIT) && $entity->allowed("edit", $record)) {
  470. $result[] = '<input type="hidden" name="atkaction" value="edit">' . '<input type="hidden" name="atkentitytype" value="' . $entity->atkEntityType()
  471. . '">' . '&nbsp;' . $this->getButton('edit') . '&nbsp;';
  472. }
  473. } elseif ($mode == "delete") {
  474. $result[] = '<input name="confirm" type="submit" class="btn_ok" value="' . $entity->text('yes') . '">';
  475. $result[] = '<input name="cancel" type="submit" class="btn_cancel" value="' . $entity->text('no') . '">';
  476. }
  477. return $result;
  478. }
  479. /**
  480. * Create a button.
  481. *
  482. * @param String $action
  483. * @param Bool $default Add the atkdefaultbutton class?
  484. * @return HTML
  485. */
  486. function getButton($action, $default = false, $label = null)
  487. {
  488. $name = "";
  489. $class = "";
  490. switch ($action) {
  491. case "save":
  492. $name = "atknoclose";
  493. $class = "btn_save";
  494. break;
  495. case "saveandclose":
  496. $name = "atksaveandclose";
  497. $class = "btn_saveandclose";
  498. break;
  499. case "cancel":
  500. $name = "atkcancel";
  501. $class = "btn_cancel";
  502. break;
  503. case "saveandedit":
  504. $name = "atksaveandcontinue";
  505. $class = "btn_saveandcontinue";
  506. break;
  507. case "saveandnext":
  508. $name = "atksaveandnext";
  509. $class = "btn_saveandnext";
  510. break;
  511. case "back":
  512. $name = "atkback";
  513. $class = "btn_cancel";
  514. $value = '<< ' . atktext($action, 'atk');
  515. break;
  516. case "edit":
  517. $name = "atkedit";
  518. $class = "btn_save";
  519. break;
  520. default:
  521. $name = $action;
  522. $class = "atkbutton";
  523. }
  524. if (!isset($value))
  525. $value = $this->m_entity->text($action);
  526. if (isset($label))
  527. $value = $label;
  528. $value = Adapto_htmlentities($value);
  529. if ($default)
  530. $class .= (!empty($class) ? ' ' : '') . 'atkdefaultbutton';
  531. if ($class != "")
  532. $class = "class=\"$class\" ";
  533. if ($value != "")
  534. $valueAttribute = "value=\"{$value}\" ";
  535. if ($name != "")
  536. $name = "name=\"" . $this->m_entity->getEditFieldPrefix() . "{$name}\" ";
  537. return '<button type="submit" ' . $class . $name . $valueAttribute . '>' . $value . '</button>';
  538. }
  539. /**
  540. * Create a dialog button.
  541. *
  542. * @param String $action The action ('save' or 'cancel')
  543. * @param String $label The label for this button
  544. * @param String $url
  545. * @param array $extraParams
  546. * @return HTML
  547. */
  548. function getDialogButton($action, $label = null, $url = null, $extraParams = array())
  549. {
  550. // Disable the button when clicked to prevent javascript errors.
  551. $onClick = 'this.disabled=\'true\';';
  552. switch ($action) {
  553. case "save":
  554. $class = "btn_save";
  555. $onClick .= atkDialog::getSaveCall($url, 'dialogform', $extraParams);
  556. break;
  557. case "cancel":
  558. $class = "btn_cancel";
  559. $onClick .= atkDialog::getCloseCall();
  560. break;
  561. default:
  562. return "";
  563. }
  564. $label = $label == null ? atktext($action, 'atk') : $label;
  565. return '<input type="button" class="' . $class . '" name="' . $label . '" value="' . $label . '" onClick="' . $onClick . '" />';
  566. }
  567. /**
  568. * Set Key/value pair in m_hidden_vars array. Saved pairs are
  569. * send as post or get vars in the next page load
  570. *
  571. * @param string $name the reference key
  572. * @param string $value the actual value
  573. */
  574. function setHiddenVar($name, $value)
  575. {
  576. $this->m_hidden_vars[$name] = $value;
  577. }
  578. /**
  579. * Return m_hidden_vars array.
  580. *
  581. * @return array
  582. */
  583. function getHiddenVars()
  584. {
  585. return $this->m_hidden_vars;
  586. }
  587. /**
  588. * Set php_file member variable
  589. *
  590. * @param string $phpfile
  591. */
  592. function setPhpFile($phpfile)
  593. {
  594. $this->m_php_file = $phpfile;
  595. }
  596. /**
  597. * Return php_file. If not set, returns theme-level dispatchfile, if not set either, return (sanitized) PHP_SELF
  598. *
  599. * @return string The name of the file to which subsequent requests should be posted.
  600. */
  601. function getPhpFile()
  602. {
  603. $theme = Adapto_ClassLoader::getInstance('Adapto_Ui_Theme');
  604. if ($this->m_php_file != "")
  605. return $this->m_php_file;
  606. return $theme->getAttribute('dispatcher', Adapto_Config::getGlobal("dispatcher", atkSelf()));
  607. }
  608. /**
  609. * Return m_hidden_vars as html input types.
  610. *
  611. * @return string
  612. */
  613. function getHiddenVarsString()
  614. {
  615. if (count($this->m_hidden_vars) == 0)
  616. return "";
  617. foreach ($this->m_hidden_vars as $hiddenVarName => $hiddenVarValue) {
  618. $varString .= '<input type="hidden" name="' . $hiddenVarName . '" value="' . $hiddenVarValue . '">';
  619. }
  620. return $varString;
  621. }
  622. /**
  623. * Configure if you want the html returned or leave it up to atkOutput.
  624. *
  625. * @param bool $returnOutput
  626. */
  627. function setReturnOutput($returnOutput)
  628. {
  629. $this->m_return_output = $returnOutput;
  630. }
  631. /**
  632. * Return the setting for returning output
  633. *
  634. * @return bool
  635. */
  636. function getReturnOutput()
  637. {
  638. return $this->m_return_output;
  639. }
  640. /**
  641. * Return a reference to the atkPage object. This object
  642. * is used to render output as an html page.
  643. *
  644. * @return object reference
  645. */
  646. function &getPage()
  647. {
  648. $page = Adapto_ClassLoader::getInstance("atk.ui.atkpage");
  649. return $page;
  650. }
  651. /**
  652. * Get the ui instance for drawing and templating purposes.
  653. *
  654. * @return atkUi An atkUi instance for drawing and templating.
  655. */
  656. function &getUi()
  657. {
  658. $ui = Adapto_ClassLoader::getInstance("atk.ui.atkui");
  659. return $ui;
  660. }
  661. /**
  662. * Generic method invoker (copied from class.atkactionhandler.inc).
  663. *
  664. * Controller methods invoked with invoke() instead of directly, have a major
  665. * advantage: the controller automatically searches for an override in the
  666. * entity. For example, If a controller calls its getSomething() method using
  667. * the invoke method, the entity may implement its own version of
  668. * getSomething() and that method will then be called instead of the
  669. * original. The controller is passed by reference to the override function
  670. * as first parameter, so if necessary, you can call the original method
  671. * from inside the override.
  672. *
  673. * The function accepts a variable number of parameters. Any parameter
  674. * that you would pass to the method, can be passed to invoke(), and
  675. * invoke() will pass the parameters on to the method.
  676. *
  677. * There is one limitation: you can't pass parameters by reference if
  678. * you use invoke().
  679. *
  680. * <b>Example:</b>
  681. *
  682. * <code>
  683. * $controller->invoke("dispatch", $postvars, $fullpage);
  684. * </code>
  685. *
  686. * This will call dispatch(&$handler, $postvars, $flags) on your entity class
  687. * if present, or dispatch($postvars, $flags) in the handler if the entity has
  688. * no override.
  689. *
  690. * @param String $methodname The name of the method to call.
  691. * @return mixed The method returns the return value of the invoked
  692. * method.
  693. */
  694. function invoke($methodname)
  695. {
  696. $arguments = func_get_args(); // Put arguments in a variable (php won't let us pass func_get_args() to other functions directly.
  697. // the first argument is $methodname, which we already defined by name.
  698. array_shift($arguments);
  699. $entity = &$this->getEntity();
  700. if ($entity !== NULL && method_exists($entity, $methodname)) {
  701. Adapto_Util_Debugger::debug("atkcontroller::invoke() Invoking '$methodname' override on entity");
  702. // We pass the original object as last parameter to the override.
  703. array_push($arguments, $this);
  704. return call_user_func_array(array(&$entity, $methodname), $arguments);
  705. } else if (method_exists($this, $methodname)) {
  706. Adapto_Util_Debugger::debug("atkcontroller::invoke() Invoking '$methodname' on controller");
  707. return call_user_func_array(array(&$this, $methodname), $arguments);
  708. }
  709. throw new Adapto_Exception("atkcontroller::invoke() Undefined method '$methodname' in Adapto_Controller");
  710. }
  711. /**
  712. * Return module name of controller
  713. *
  714. * @return string module name
  715. */
  716. function getModuleName()
  717. {
  718. return $this->m_module_name;
  719. }
  720. /**
  721. * Return controller name
  722. *
  723. * @return string controller name
  724. */
  725. function getName()
  726. {
  727. return $this->m_name;
  728. }
  729. }
  730. ?>