PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/library/core/class.dispatcher.php

https://github.com/wufoo/Garden
PHP | 625 lines | 333 code | 88 blank | 204 comment | 86 complexity | c37697f0507b73d8965a1f59f4ce76d1 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, BSD-3-Clause, MIT
  1. <?php if (!defined('APPLICATION')) exit();
  2. /*
  3. Copyright 2008, 2009 Vanilla Forums Inc.
  4. This file is part of Garden.
  5. Garden is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
  6. Garden is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  7. You should have received a copy of the GNU General Public License along with Garden. If not, see <http://www.gnu.org/licenses/>.
  8. Contact Vanilla Forums Inc. at support [at] vanillaforums [dot] com
  9. */
  10. /**
  11. * Dispatcher handles all requests.
  12. *
  13. * @author Mark O'Sullivan
  14. * @copyright 2003 Mark O'Sullivan
  15. * @license http://www.opensource.org/licenses/gpl-2.0.php GPL
  16. * @package Garden
  17. * @version @@GARDEN-VERSION@@
  18. * @namespace Garden.Core
  19. */
  20. class Gdn_Dispatcher extends Gdn_Pluggable {
  21. /**
  22. * An array of folders within the application that are OK to search through
  23. * for controllers. This property is filled by the applications array
  24. * located in /conf/applications.php and included in /bootstrap.php
  25. *
  26. * @var array
  27. */
  28. private $_EnabledApplicationFolders;
  29. /**
  30. * An associative array of ApplicationName => ApplicationFolder. This
  31. * property is filled by the applications array located in
  32. * /conf/applications.php and included in /bootstrap.php
  33. *
  34. * @var array
  35. */
  36. private $_EnabledApplications;
  37. /**
  38. * The currently requested url (defined in _AnalyzeRequest)
  39. *
  40. * @var string
  41. */
  42. public $Request;
  43. /**
  44. * The name of the application folder that contains the controller that has
  45. * been requested.
  46. *
  47. * @var string
  48. */
  49. private $_ApplicationFolder;
  50. /**
  51. * An associative collection of AssetName => Strings that will get passed
  52. * into the controller once it has been instantiated.
  53. *
  54. * @var array
  55. */
  56. private $_AssetCollection;
  57. /**
  58. * The name of the controller folder that contains the controller that has
  59. * been requested.
  60. *
  61. * @var string
  62. */
  63. private $_ControllerFolder;
  64. /**
  65. * The name of the controller to be dispatched.
  66. *
  67. * @var string
  68. */
  69. private $_ControllerName;
  70. /**
  71. * The method of the controller to be called.
  72. *
  73. * @var string
  74. */
  75. private $_ControllerMethod;
  76. /**
  77. * Any query string arguments supplied to the controller method.
  78. *
  79. * @var string
  80. */
  81. private $_ControllerMethodArgs = array();
  82. /**
  83. * @var string|FALSE The delivery method to set on the controller.
  84. */
  85. private $_DeliveryMethod = FALSE;
  86. /**
  87. * @var string|FALSE The delivery type to set on the controller.
  88. */
  89. private $_DeliveryType = FALSE;
  90. /**
  91. * An associative collection of variables that will get passed into the
  92. * controller as properties once it has been instantiated.
  93. *
  94. * @var array
  95. */
  96. private $_PropertyCollection;
  97. /**
  98. * Defined by the url of the request: SYNDICATION_RSS, SYNDICATION_ATOM, or
  99. * SYNDICATION_NONE (default).
  100. *
  101. * @var string
  102. */
  103. private $_SyndicationMethod;
  104. /**
  105. * Class constructor.
  106. */
  107. public function __construct() {
  108. parent::__construct();
  109. $this->_EnabledApplicationFolders = array();
  110. $this->Request = '';
  111. $this->_ApplicationFolder = '';
  112. $this->_AssetCollection = array();
  113. $this->_ControllerFolder = '';
  114. $this->_ControllerName = '';
  115. $this->_ControllerMethod = '';
  116. $this->_ControllerMethodArgs = array();
  117. $this->_PropertyCollection = array();
  118. }
  119. public function Cleanup() {
  120. // Destruct the db connection;
  121. $Database = Gdn::Database();
  122. if($Database != null)
  123. $Database->CloseConnection();
  124. }
  125. /**
  126. * Return the properly formatted controller class name.
  127. */
  128. public function ControllerName() {
  129. return $this->_ControllerName.'Controller';
  130. }
  131. public function Application() {
  132. return $this->_ApplicationFolder;
  133. }
  134. public function Controller() {
  135. return $this->_ControllerName;
  136. }
  137. public function ControllerMethod() {
  138. return $this->_ControllerMethod;
  139. }
  140. public function ControllerArguments() {
  141. return $this->_ControllerMethodArgs;
  142. }
  143. /**
  144. * Analyzes the supplied query string and decides how to dispatch the request.
  145. */
  146. public function Dispatch($ImportRequest = NULL, $Permanent = TRUE) {
  147. if ($ImportRequest && is_string($ImportRequest))
  148. $ImportRequest = Gdn_Request::Create()->FromEnvironment()->WithURI($ImportRequest);
  149. if (is_a($ImportRequest, 'Gdn_Request') && $Permanent) {
  150. Gdn::Request($ImportRequest);
  151. }
  152. $Request = is_a($ImportRequest, 'Gdn_Request') ? $ImportRequest : Gdn::Request();
  153. if (Gdn::Config('Garden.UpdateMode', FALSE)) {
  154. if (!Gdn::Session()->CheckPermission('Garden.Settings.GlobalPrivs')) {
  155. // Updatemode, and this user is not root admin
  156. $Request->WithURI(Gdn::Router()->GetDestination('UpdateMode'));
  157. }
  158. }
  159. $this->FireEvent('BeforeDispatch');
  160. $this->_AnalyzeRequest($Request);
  161. // Send user to login page if this is a private community (with some minor exceptions)
  162. if (
  163. C('Garden.PrivateCommunity')
  164. && $this->ControllerName() != 'EntryController'
  165. && !Gdn::Session()->IsValid()
  166. && !InArrayI($this->ControllerMethod(), array('UsernameAvailable', 'EmailAvailable', 'TermsOfService'))
  167. ) {
  168. Redirect(Gdn::Authenticator()->SignInUrl($this->Request));
  169. exit();
  170. }
  171. /*
  172. echo "<br />Gdn::Request thinks: ".Gdn::Request()->Path();
  173. echo "<br />Gdn::Request also suggests: output=".Gdn::Request()->OutputFormat().", filename=".Gdn::Request()->Filename();
  174. echo '<br />Request: '.$this->Request;
  175. echo '<br />App folder: '.$this->_ApplicationFolder;
  176. echo '<br />Controller folder: '.$this->_ControllerFolder;
  177. echo '<br />ControllerName: '.$this->_ControllerName;
  178. echo '<br />ControllerMethod: '.$this->_ControllerMethod;
  179. */
  180. $ControllerName = $this->ControllerName();
  181. if ($ControllerName != '' && class_exists($ControllerName)) {
  182. // Create it and call the appropriate method/action
  183. $Controller = new $ControllerName();
  184. // Pass along any assets
  185. if (is_array($this->_AssetCollection)) {
  186. foreach ($this->_AssetCollection as $AssetName => $Assets) {
  187. foreach ($Assets as $Asset) {
  188. $Controller->AddAsset($AssetName, $Asset);
  189. }
  190. }
  191. }
  192. // Instantiate Imported & Uses classes
  193. $Controller->GetImports();
  194. // Pass in the syndication method
  195. $Controller->SyndicationMethod = $this->_SyndicationMethod;
  196. // Pass along the request
  197. $Controller->SelfUrl = $this->Request;
  198. // Pass along any objects
  199. foreach($this->_PropertyCollection as $Name => $Mixed) {
  200. $Controller->$Name = $Mixed;
  201. }
  202. // Set up a default controller method in case one isn't defined.
  203. $ControllerMethod = str_replace('_', '', $this->_ControllerMethod);
  204. $Controller->OriginalRequestMethod = $ControllerMethod;
  205. $this->FireEvent('AfterAnalyzeRequest');
  206. // Take enabled plugins into account, as well
  207. $PluginManagerHasReplacementMethod = Gdn::PluginManager()->HasNewMethod($this->ControllerName(), $this->_ControllerMethod);
  208. if (!$PluginManagerHasReplacementMethod && ($this->_ControllerMethod == '' || !method_exists($Controller, $ControllerMethod))) {
  209. // Check to see if there is an 'x' version of the method.
  210. if (method_exists($Controller, 'x'.$ControllerMethod)) {
  211. // $PluginManagerHasReplacementMethod = TRUE;
  212. $ControllerMethod = 'x'.$ControllerMethod;
  213. } else {
  214. if ($this->_ControllerMethod != '')
  215. array_unshift($this->_ControllerMethodArgs, $this->_ControllerMethod);
  216. $this->_ControllerMethod = 'Index';
  217. $ControllerMethod = 'Index';
  218. $PluginManagerHasReplacementMethod = Gdn::PluginManager()->HasNewMethod($this->ControllerName(), $this->_ControllerMethod);
  219. }
  220. }
  221. // Pass in the querystring values
  222. $Controller->ApplicationFolder = $this->_ApplicationFolder;
  223. $Controller->Application = $this->EnabledApplication();
  224. $Controller->ControllerFolder = $this->_ControllerFolder;
  225. $Controller->RequestMethod = $this->_ControllerMethod;
  226. $Controller->RequestArgs = $this->_ControllerMethodArgs;
  227. $Controller->Request = $Request;
  228. $Controller->DeliveryType($Request->GetValue('DeliveryType', $this->_DeliveryType));
  229. $Controller->DeliveryMethod($Request->GetValue('DeliveryMethod', $this->_DeliveryMethod));
  230. $this->FireEvent('BeforeControllerMethod');
  231. // Set special controller method options for REST APIs.
  232. $this->_ReflectControllerArgs($Controller);
  233. $Controller->Initialize();
  234. // Call the requested method on the controller - error out if not defined.
  235. if ($PluginManagerHasReplacementMethod || method_exists($Controller, $ControllerMethod)) {
  236. // call_user_func_array is too slow!!
  237. //call_user_func_array(array($Controller, $ControllerMethod), $this->_ControllerMethodArgs);
  238. if ($PluginManagerHasReplacementMethod) {
  239. Gdn::PluginManager()->CallNewMethod($Controller, $Controller->ControllerName, $ControllerMethod);
  240. } else {
  241. $Args = $this->_ControllerMethodArgs;
  242. $Count = count($Args);
  243. try {
  244. call_user_func_array(array($Controller, $ControllerMethod), $Args);
  245. } catch (Exception $Ex) {
  246. $Controller->RenderException($Ex);
  247. exit();
  248. }
  249. }
  250. } else {
  251. Gdn::Request()->WithRoute('Default404');
  252. return $this->Dispatch();
  253. }
  254. }
  255. }
  256. /**
  257. * Undocumented method.
  258. *
  259. * @param string $EnabledApplications
  260. * @todo Method EnabledApplicationFolders() and $EnabledApplications needs descriptions.
  261. */
  262. public function EnabledApplicationFolders($EnabledApplications = '') {
  263. if ($EnabledApplications != '' && count($this->_EnabledApplicationFolders) == 0) {
  264. $this->_EnabledApplications = $EnabledApplications;
  265. $this->_EnabledApplicationFolders = array_values($EnabledApplications);
  266. }
  267. return $this->_EnabledApplicationFolders;
  268. }
  269. /**
  270. * Returns the name of the enabled application based on $ApplicationFolder.
  271. *
  272. * @param string The application folder related to the application name you want to return.
  273. */
  274. public function EnabledApplication($ApplicationFolder = '') {
  275. if ($ApplicationFolder == '')
  276. $ApplicationFolder = $this->_ApplicationFolder;
  277. $EnabledApplication = array_keys($this->_EnabledApplications, $ApplicationFolder);
  278. $EnabledApplication = count($EnabledApplication) > 0 ? $EnabledApplication[0] : '';
  279. $this->EventArguments['EnabledApplication'] = $EnabledApplication;
  280. $this->FireEvent('AfterEnabledApplication');
  281. return $EnabledApplication;
  282. }
  283. /**
  284. * Allows the passing of a string to the controller's asset collection.
  285. *
  286. * @param string $AssetName The name of the asset collection to add the string to.
  287. * @param mixed $Asset The string asset to be added. The asset can be one of two things.
  288. * - <b>string</b>: The string will be rendered to the page.
  289. * - <b>Gdn_IModule</b>: The Gdn_IModule::Render() method will be called when the asset is rendered.
  290. */
  291. public function PassAsset($AssetName, $Asset) {
  292. $this->_AssetCollection[$AssetName][] = $Asset;
  293. }
  294. /**
  295. * Allows the passing of any variable to the controller as a property.
  296. *
  297. * @param string $Name The name of the property to assign the variable to.
  298. * @param mixed $Mixed The variable to be passed as a property of the controller.
  299. */
  300. public function PassProperty($Name, $Mixed) {
  301. $this->_PropertyCollection[$Name] = $Mixed;
  302. }
  303. /**
  304. * Parses the query string looking for supplied request parameters. Places
  305. * anything useful into this object's Controller properties.
  306. *
  307. * @param int $FolderDepth
  308. * @todo $folderDepth needs a description.
  309. */
  310. protected function _AnalyzeRequest(&$Request, $FolderDepth = 1) {
  311. // Here is the basic format of a request:
  312. // [/application]/controller[/method[.json|.xml]]/argn|argn=valn
  313. // Here are some examples of what this method could/would receive:
  314. // /application/controller/method/argn
  315. // /controller/method/argn
  316. // /application/controller/argn
  317. // /controller/argn
  318. // /controller
  319. // Clear the slate
  320. $this->_ApplicationFolder = '';
  321. $this->_ControllerFolder = '';
  322. $this->_ControllerName = '';
  323. $this->_ControllerMethod = 'index';
  324. $this->_ControllerMethodArgs = array();
  325. $this->Request = $Request->Path(TRUE);
  326. $PathAndQuery = $Request->PathAndQuery();
  327. //$Router = Gdn::Router();
  328. $MatchRoute = Gdn::Router()->MatchRoute($PathAndQuery);
  329. // We have a route. Take action.
  330. if ($MatchRoute !== FALSE) {
  331. switch ($MatchRoute['Type']) {
  332. case 'Internal':
  333. $Request->PathAndQuery($MatchRoute['FinalDestination']);
  334. $this->Request = $MatchRoute['FinalDestination'];
  335. break;
  336. case 'Temporary':
  337. header( "HTTP/1.1 302 Moved Temporarily" );
  338. header( "Location: ".$MatchRoute['FinalDestination'] );
  339. exit();
  340. break;
  341. case 'Permanent':
  342. header( "HTTP/1.1 301 Moved Permanently" );
  343. header( "Location: ".$MatchRoute['FinalDestination'] );
  344. exit();
  345. break;
  346. case 'NotAuthorized':
  347. header( "HTTP/1.1 401 Not Authorized" );
  348. $this->Request = $MatchRoute['FinalDestination'];
  349. break;
  350. case 'NotFound':
  351. header( "HTTP/1.1 404 Not Found" );
  352. $this->Request = $MatchRoute['FinalDestination'];
  353. break;
  354. }
  355. }
  356. switch ($Request->OutputFormat()) {
  357. case 'rss':
  358. $this->_SyndicationMethod = SYNDICATION_RSS;
  359. break;
  360. case 'atom':
  361. $this->_SyndicationMethod = SYNDICATION_ATOM;
  362. break;
  363. case 'default':
  364. default:
  365. $this->_SyndicationMethod = SYNDICATION_NONE;
  366. break;
  367. }
  368. if ($this->Request == '')
  369. {
  370. $DefaultController = Gdn::Router()->GetRoute('DefaultController');
  371. $this->Request = $DefaultController['Destination'];
  372. }
  373. $Parts = explode('/', $this->Request);
  374. $Length = count($Parts);
  375. if ($Length == 1 || $FolderDepth <= 0) {
  376. $FolderDepth = 0;
  377. list($this->_ControllerName, $this->_DeliveryMethod) = $this->_SplitDeliveryMethod($Parts[0]);
  378. $Parts[0] = $this->_ControllerName;
  379. $this->_MapParts($Parts, 0);
  380. $this->_FetchController(TRUE); // Throw an error if this fails because there's nothing else to check
  381. } else if ($Length == 2) {
  382. // Force a depth of 1 because only one of the two url parts can be a folder.
  383. $FolderDepth = 1;
  384. }
  385. if ($FolderDepth == 2) {
  386. $this->_ApplicationFolder = $Parts[0];
  387. $this->_ControllerFolder = $Parts[1];
  388. $this->_MapParts($Parts, 2);
  389. if (!$this->_FetchController()) {
  390. // echo '<div>Failed. AppFolder: '.$this->_ApplicationFolder.'; Cont Folder: '.$this->_ControllerFolder.'; Cont: '.$this->_ControllerName.';</div>';
  391. $this->_AnalyzeRequest($Request, 1);
  392. }
  393. } else if ($FolderDepth == 1) {
  394. // Try the application folder first
  395. $Found = FALSE;
  396. if (in_array($Parts[0], $this->EnabledApplicationFolders())) {
  397. // Check to see if the first part is an application
  398. $this->_ApplicationFolder = $Parts[0];
  399. $this->_MapParts($Parts, 1);
  400. $Found = $this->_FetchController();
  401. }
  402. if (!$Found) {
  403. // echo '<div>Failed. AppFolder: '.$this->_ApplicationFolder.'; Cont Folder: '.$this->_ControllerFolder.'; Cont: '.$this->_ControllerName.';</div>';
  404. // Check to see if the first part is a controller folder
  405. $this->_ApplicationFolder = '';
  406. $this->_ControllerFolder = $Parts[0];
  407. $this->_MapParts($Parts, 1);
  408. if (!$this->_FetchController()) {
  409. // echo '<div>Failed. AppFolder: '.$this->_ApplicationFolder.'; Cont Folder: '.$this->_ControllerFolder.'; Cont: '.$this->_ControllerName.';</div>';
  410. $this->_AnalyzeRequest($Request, 0);
  411. }
  412. }
  413. }
  414. if (in_array($this->_DeliveryMethod, array(DELIVERY_METHOD_JSON, DELIVERY_METHOD_XML)))
  415. $this->_DeliveryType = DELIVERY_TYPE_DATA;
  416. }
  417. /**
  418. * Searches through the /cache/controller_mappings.php file for the requested
  419. * controller. If it doesn't find it, it searches through the entire
  420. * application's folders for the requested controller. If it finds the
  421. * controller, it adds the mapping to /cache/controller_mappings.php so it
  422. * won't need to search again. If it doesn't find the controller file
  423. * anywhere, it throws a fatal error.
  424. *
  425. * @param boolean $ThrowErrorOnFailure
  426. * @todo $ThrowErrorOnFailure needs a description.
  427. */
  428. private function _FetchController($ThrowErrorOnFailure = FALSE) {
  429. $ControllerWhiteList = $this->EnabledApplicationFolders();
  430. // Don't include it if it's already been included
  431. if (!class_exists($this->ControllerName())) {
  432. $PathParts = array('controllers');
  433. if ($this->_ControllerFolder != '')
  434. $PathParts[] = $this->_ControllerFolder;
  435. $PathParts[] = 'class.'.strtolower($this->_ControllerName).'controller.php';
  436. $ControllerFileName = CombinePaths($PathParts);
  437. // Limit the white list to the specified application folder if it was in the request
  438. if ($this->_ApplicationFolder != '' && InArrayI($this->_ApplicationFolder, $ControllerWhiteList))
  439. $ControllerWhiteList = array($this->_ApplicationFolder);
  440. $ControllerPath = Gdn_FileSystem::FindByMapping('controller', PATH_APPLICATIONS, $ControllerWhiteList, $ControllerFileName);
  441. if ($ControllerPath !== FALSE) {
  442. // Strip the "Application Folder" from the controller path (this is
  443. // used by the controller for various purposes. ie. knowing which
  444. // application to search in for a view file).
  445. $this->_ApplicationFolder = explode(DS, str_replace(PATH_APPLICATIONS . DS, '', $ControllerPath));
  446. $this->_ApplicationFolder = $this->_ApplicationFolder[0];
  447. $AppControllerName = ucfirst(strtolower($this->_ApplicationFolder)).'Controller';
  448. // Load the application's master controller
  449. if (!class_exists($AppControllerName))
  450. require_once(CombinePaths(array(PATH_APPLICATIONS, $this->_ApplicationFolder, 'controllers', 'class.'.strtolower($this->_ApplicationFolder).'controller.php')));
  451. // Now load the library (no need to check for existence - couldn't
  452. // have made it here if it didn't exist).
  453. require_once($ControllerPath);
  454. }
  455. }
  456. if (!class_exists($this->ControllerName())) {
  457. if ($ThrowErrorOnFailure === TRUE) {
  458. if (ForceBool(Gdn::Config('Garden.Debug'))) {
  459. trigger_error(ErrorMessage('Controller not found: '.$this->ControllerName(), 'Dispatcher', '_FetchController'), E_USER_ERROR);
  460. } else {
  461. $MissingRoute = Gdn::Router()->GetRoute('Default404');
  462. // Return a 404 message
  463. list($this->_ApplicationFolder, $this->_ControllerName, $this->_ControllerMethod) = explode('/', $MissingRoute['Destination']);
  464. $ControllerFileName = CombinePaths(array('controllers', 'class.' . strtolower($this->_ControllerName) . 'controller.php'));
  465. $ControllerPath = Gdn_FileSystem::FindByMapping('controller', PATH_APPLICATIONS, $ControllerWhiteList, $ControllerFileName);
  466. $this->_ApplicationFolder = explode(DS, str_replace(PATH_APPLICATIONS . DS, '', $ControllerPath));
  467. $this->_ApplicationFolder = $this->_ApplicationFolder[0];
  468. require_once(CombinePaths(array(PATH_APPLICATIONS, $this->_ApplicationFolder, 'controllers', 'class.'.strtolower($this->_ApplicationFolder).'controller.php')));
  469. require_once($ControllerPath);
  470. }
  471. }
  472. return FALSE;
  473. } else {
  474. return TRUE;
  475. }
  476. }
  477. /**
  478. * An internal method used to map parts of the request to various properties
  479. * of this object that represent the controller, controller method, and
  480. * controller method arguments.
  481. *
  482. * @param array $Parts An array of parts of the request.
  483. * @param int $ControllerKey An integer representing the key of the controller in the $Parts array.
  484. */
  485. private function _MapParts($Parts, $ControllerKey) {
  486. $Length = count($Parts);
  487. if ($Length > $ControllerKey)
  488. $this->_ControllerName = ucfirst(strtolower($Parts[$ControllerKey]));
  489. if ($Length > $ControllerKey + 1)
  490. list($this->_ControllerMethod, $this->_DeliveryMethod) = $this->_SplitDeliveryMethod($Parts[$ControllerKey + 1]);
  491. if ($Length > $ControllerKey + 2) {
  492. for ($i = $ControllerKey + 2; $i < $Length; ++$i) {
  493. if ($Parts[$i] != '')
  494. $this->_ControllerMethodArgs[] = $Parts[$i];
  495. }
  496. }
  497. }
  498. protected function _ReflectControllerArgs($Controller) {
  499. // Reflect the controller arguments based on the get.
  500. if (count($Controller->Request->Get()) == 0)
  501. return;
  502. if (!method_exists($Controller, $this->_ControllerMethod))
  503. return;
  504. $Meth = new ReflectionMethod($Controller, $this->_ControllerMethod);
  505. $MethArgs = $Meth->getParameters();
  506. $Args = array();
  507. $Get = array_change_key_case($Controller->Request->Get());
  508. $MissingArgs = array();
  509. // Set all of the parameters.
  510. foreach ($MethArgs as $Index => $MethParam) {
  511. $ParamName = strtolower($MethParam->getName());
  512. if (isset($this->_ControllerMethodArgs[$Index]))
  513. $Args[] = $this->_ControllerMethodArgs[$Index];
  514. elseif (isset($Get[$ParamName]))
  515. $Args[] = $Get[$ParamName];
  516. elseif ($MethParam->isDefaultValueAvailable())
  517. $Args[] = $MethParam->getDefaultValue();
  518. else {
  519. $Args[] = NULL;
  520. $MissingArgs[] = "$Index: $ParamName";
  521. }
  522. }
  523. $this->_ControllerMethodArgs = $Args;
  524. }
  525. protected function _SplitDeliveryMethod($Name) {
  526. $Parts = explode('.', $Name, 2);
  527. if (count($Parts) >= 2) {
  528. if (in_array(strtoupper($Parts[1]), array(DELIVERY_METHOD_JSON, DELIVERY_METHOD_XHTML, DELIVERY_METHOD_XML))) {
  529. return array($Parts[0], strtoupper($Parts[1]));
  530. } else {
  531. return array($Name, $this->_DeliveryMethod);
  532. }
  533. } else {
  534. return array($Name, $this->_DeliveryMethod);
  535. }
  536. }
  537. }