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

/app/Mage.php

https://bitbucket.org/claudiu_marginean/magento-hg-mirror
PHP | 897 lines | 464 code | 86 blank | 347 comment | 68 complexity | 4d3d4da7886883e3f74bb45a8b949660 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, LGPL-2.1, GPL-2.0, WTFPL
  1. <?php
  2. /**
  3. * Magento
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Open Software License (OSL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/osl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Mage
  22. * @package Mage_Core
  23. * @copyright Copyright (c) 2008 Irubin Consulting Inc. DBA Varien (http://www.varien.com)
  24. * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
  25. */
  26. define('DS', DIRECTORY_SEPARATOR);
  27. define('PS', PATH_SEPARATOR);
  28. define('BP', dirname(dirname(__FILE__)));
  29. Mage::register('original_include_path', get_include_path());
  30. if (defined('COMPILER_INCLUDE_PATH')) {
  31. $appPath = COMPILER_INCLUDE_PATH;
  32. set_include_path($appPath . PS . Mage::registry('original_include_path'));
  33. include_once "Mage_Core_functions.php";
  34. include_once "Varien_Autoload.php";
  35. } else {
  36. /**
  37. * Set include path
  38. */
  39. $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'local';
  40. $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'community';
  41. $paths[] = BP . DS . 'app' . DS . 'code' . DS . 'core';
  42. $paths[] = BP . DS . 'lib';
  43. $appPath = implode(PS, $paths);
  44. set_include_path($appPath . PS . Mage::registry('original_include_path'));
  45. include_once "Mage/Core/functions.php";
  46. include_once "Varien/Autoload.php";
  47. }
  48. Varien_Autoload::register();
  49. /**
  50. * Main Mage hub class
  51. *
  52. * @author Magento Core Team <core@magentocommerce.com>
  53. */
  54. final class Mage
  55. {
  56. /**
  57. * Registry collection
  58. *
  59. * @var array
  60. */
  61. static private $_registry = array();
  62. /**
  63. * Application root absolute path
  64. *
  65. * @var string
  66. */
  67. static private $_appRoot;
  68. /**
  69. * Application model
  70. *
  71. * @var Mage_Core_Model_App
  72. */
  73. static private $_app;
  74. /**
  75. * Config Model
  76. *
  77. * @var Mage_Core_Model_Config
  78. */
  79. static private $_config;
  80. /**
  81. * Event Collection Object
  82. *
  83. * @var Varien_Event_Collection
  84. */
  85. static private $_events;
  86. /**
  87. * Object cache instance
  88. *
  89. * @var Varien_Object_Cache
  90. */
  91. static private $_objects;
  92. /**
  93. * Is downloader flag
  94. *
  95. * @var bool
  96. */
  97. static private $_isDownloader = false;
  98. /**
  99. * Is developer mode flag
  100. *
  101. * @var bool
  102. */
  103. static private $_isDeveloperMode = false;
  104. /**
  105. * Is allow throw Exception about headers already sent
  106. *
  107. * @var bool
  108. */
  109. public static $headersSentThrowsException = true;
  110. /**
  111. * Is installed flag
  112. *
  113. * @var bool
  114. */
  115. static private $_isInstalled;
  116. /**
  117. * Gets the current Magento version string
  118. * @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
  119. *
  120. * @return string
  121. */
  122. public static function getVersion()
  123. {
  124. $i = self::getVersionInfo();
  125. return trim("{$i['major']}.{$i['minor']}.{$i['revision']}" . ($i['patch'] != '' ? ".{$i['patch']}" : "") . "-{$i['stability']}{$i['number']}", '.-');
  126. }
  127. /**
  128. * Gets the detailed Magento version information
  129. * @link http://www.magentocommerce.com/blog/new-community-edition-release-process/
  130. *
  131. * @return array
  132. */
  133. public static function getVersionInfo()
  134. {
  135. return array(
  136. 'major' => '1',
  137. 'minor' => '5',
  138. 'revision' => '1',
  139. 'patch' => '0',
  140. 'stability' => '',
  141. 'number' => '',
  142. );
  143. }
  144. /**
  145. * Set all my static data to defaults
  146. *
  147. */
  148. public static function reset()
  149. {
  150. self::$_registry = array();
  151. self::$_app = null;
  152. self::$_config = null;
  153. self::$_events = null;
  154. self::$_objects = null;
  155. self::$_isDownloader = false;
  156. self::$_isDeveloperMode = false;
  157. // do not reset $headersSentThrowsException
  158. }
  159. /**
  160. * Register a new variable
  161. *
  162. * @param string $key
  163. * @param mixed $value
  164. * @param bool $graceful
  165. * @throws Mage_Core_Exception
  166. */
  167. public static function register($key, $value, $graceful = false)
  168. {
  169. if (isset(self::$_registry[$key])) {
  170. if ($graceful) {
  171. return;
  172. }
  173. self::throwException('Mage registry key "'.$key.'" already exists');
  174. }
  175. self::$_registry[$key] = $value;
  176. }
  177. /**
  178. * Unregister a variable from register by key
  179. *
  180. * @param string $key
  181. */
  182. public static function unregister($key)
  183. {
  184. if (isset(self::$_registry[$key])) {
  185. if (is_object(self::$_registry[$key]) && (method_exists(self::$_registry[$key], '__destruct'))) {
  186. self::$_registry[$key]->__destruct();
  187. }
  188. unset(self::$_registry[$key]);
  189. }
  190. }
  191. /**
  192. * Retrieve a value from registry by a key
  193. *
  194. * @param string $key
  195. * @return mixed
  196. */
  197. public static function registry($key)
  198. {
  199. if (isset(self::$_registry[$key])) {
  200. return self::$_registry[$key];
  201. }
  202. return null;
  203. }
  204. /**
  205. * Set application root absolute path
  206. *
  207. * @param string $appRoot
  208. * @throws Mage_Core_Exception
  209. */
  210. public static function setRoot($appRoot = '')
  211. {
  212. if (self::$_appRoot) {
  213. return ;
  214. }
  215. if ('' === $appRoot) {
  216. // automagically find application root by dirname of Mage.php
  217. $appRoot = dirname(__FILE__);
  218. }
  219. $appRoot = realpath($appRoot);
  220. if (is_dir($appRoot) and is_readable($appRoot)) {
  221. self::$_appRoot = $appRoot;
  222. } else {
  223. self::throwException($appRoot . ' is not a directory or not readable by this user');
  224. }
  225. }
  226. /**
  227. * Retrieve application root absolute path
  228. *
  229. * @return string
  230. */
  231. public static function getRoot()
  232. {
  233. return self::$_appRoot;
  234. }
  235. /**
  236. * Retrieve Events Collection
  237. *
  238. * @return Varien_Event_Collection $collection
  239. */
  240. public static function getEvents()
  241. {
  242. return self::$_events;
  243. }
  244. /**
  245. * Varien Objects Cache
  246. *
  247. * @param string $key optional, if specified will load this key
  248. * @return Varien_Object_Cache
  249. */
  250. public static function objects($key = null)
  251. {
  252. if (!self::$_objects) {
  253. self::$_objects = new Varien_Object_Cache;
  254. }
  255. if (is_null($key)) {
  256. return self::$_objects;
  257. } else {
  258. return self::$_objects->load($key);
  259. }
  260. }
  261. /**
  262. * Retrieve application root absolute path
  263. *
  264. * @param string $type
  265. * @return string
  266. */
  267. public static function getBaseDir($type = 'base')
  268. {
  269. return self::getConfig()->getOptions()->getDir($type);
  270. }
  271. /**
  272. * Retrieve module absolute path by directory type
  273. *
  274. * @param string $type
  275. * @param string $moduleName
  276. * @return string
  277. */
  278. public static function getModuleDir($type, $moduleName)
  279. {
  280. return self::getConfig()->getModuleDir($type, $moduleName);
  281. }
  282. /**
  283. * Retrieve config value for store by path
  284. *
  285. * @param string $path
  286. * @param mixed $store
  287. * @return mixed
  288. */
  289. public static function getStoreConfig($path, $store = null)
  290. {
  291. return self::app()->getStore($store)->getConfig($path);
  292. }
  293. /**
  294. * Retrieve config flag for store by path
  295. *
  296. * @param string $path
  297. * @param mixed $store
  298. * @return bool
  299. */
  300. public static function getStoreConfigFlag($path, $store = null)
  301. {
  302. $flag = strtolower(self::getStoreConfig($path, $store));
  303. if (!empty($flag) && 'false' !== $flag) {
  304. return true;
  305. } else {
  306. return false;
  307. }
  308. }
  309. /**
  310. * Get base URL path by type
  311. *
  312. * @param string $type
  313. * @return string
  314. */
  315. public static function getBaseUrl($type = Mage_Core_Model_Store::URL_TYPE_LINK, $secure = null)
  316. {
  317. return self::app()->getStore()->getBaseUrl($type, $secure);
  318. }
  319. /**
  320. * Generate url by route and parameters
  321. *
  322. * @param string $route
  323. * @param array $params
  324. * @return string
  325. */
  326. public static function getUrl($route = '', $params = array())
  327. {
  328. return self::getModel('core/url')->getUrl($route, $params);
  329. }
  330. /**
  331. * Get design package singleton
  332. *
  333. * @return Mage_Core_Model_Design_Package
  334. */
  335. public static function getDesign()
  336. {
  337. return self::getSingleton('core/design_package');
  338. }
  339. /**
  340. * Retrieve a config instance
  341. *
  342. * @return Mage_Core_Model_Config
  343. */
  344. public static function getConfig()
  345. {
  346. return self::$_config;
  347. }
  348. /**
  349. * Add observer to even object
  350. *
  351. * @param string $eventName
  352. * @param callback $callback
  353. * @param array $arguments
  354. * @param string $observerName
  355. */
  356. public static function addObserver($eventName, $callback, $data = array(), $observerName = '', $observerClass = '')
  357. {
  358. if ($observerClass == '') {
  359. $observerClass = 'Varien_Event_Observer';
  360. }
  361. $observer = new $observerClass();
  362. $observer->setName($observerName)->addData($data)->setEventName($eventName)->setCallback($callback);
  363. return self::getEvents()->addObserver($observer);
  364. }
  365. /**
  366. * Dispatch event
  367. *
  368. * Calls all observer callbacks registered for this event
  369. * and multiobservers matching event name pattern
  370. *
  371. * @param string $name
  372. * @param array $args
  373. * @return Mage_Core_Model_App
  374. */
  375. public static function dispatchEvent($name, array $data = array())
  376. {
  377. Varien_Profiler::start('DISPATCH EVENT:'.$name);
  378. $result = self::app()->dispatchEvent($name, $data);
  379. #$result = self::registry('events')->dispatch($name, $data);
  380. Varien_Profiler::stop('DISPATCH EVENT:'.$name);
  381. return $result;
  382. }
  383. /**
  384. * Retrieve model object
  385. *
  386. * @link Mage_Core_Model_Config::getModelInstance
  387. * @param string $modelClass
  388. * @param array $arguments
  389. * @return Mage_Core_Model_Abstract
  390. */
  391. public static function getModel($modelClass = '', $arguments = array())
  392. {
  393. return self::getConfig()->getModelInstance($modelClass, $arguments);
  394. }
  395. /**
  396. * Retrieve model object singleton
  397. *
  398. * @param string $modelClass
  399. * @param array $arguments
  400. * @return Mage_Core_Model_Abstract
  401. */
  402. public static function getSingleton($modelClass='', array $arguments=array())
  403. {
  404. $registryKey = '_singleton/'.$modelClass;
  405. if (!self::registry($registryKey)) {
  406. self::register($registryKey, self::getModel($modelClass, $arguments));
  407. }
  408. return self::registry($registryKey);
  409. }
  410. /**
  411. * Retrieve object of resource model
  412. *
  413. * @param string $modelClass
  414. * @param array $arguments
  415. * @return Object
  416. */
  417. public static function getResourceModel($modelClass, $arguments = array())
  418. {
  419. return self::getConfig()->getResourceModelInstance($modelClass, $arguments);
  420. }
  421. /**
  422. * Retrieve Controller instance by ClassName
  423. *
  424. * @param string $class
  425. * @param Mage_Core_Controller_Request_Http $request
  426. * @param Mage_Core_Controller_Response_Http $response
  427. * @param array $invokeArgs
  428. * @return Mage_Core_Controller_Front_Action
  429. */
  430. public static function getControllerInstance($class, $request, $response, array $invokeArgs = array())
  431. {
  432. return new $class($request, $response, $invokeArgs);
  433. }
  434. /**
  435. * Retrieve resource vodel object singleton
  436. *
  437. * @param string $modelClass
  438. * @param array $arguments
  439. * @return object
  440. */
  441. public static function getResourceSingleton($modelClass = '', array $arguments = array())
  442. {
  443. $registryKey = '_resource_singleton/'.$modelClass;
  444. if (!self::registry($registryKey)) {
  445. self::register($registryKey, self::getResourceModel($modelClass, $arguments));
  446. }
  447. return self::registry($registryKey);
  448. }
  449. /**
  450. * Deprecated, use self::helper()
  451. *
  452. * @param string $type
  453. * @return object
  454. */
  455. public static function getBlockSingleton($type)
  456. {
  457. $action = self::app()->getFrontController()->getAction();
  458. return $action ? $action->getLayout()->getBlockSingleton($type) : false;
  459. }
  460. /**
  461. * Retrieve helper object
  462. *
  463. * @param string $name the helper name
  464. * @return Mage_Core_Helper_Abstract
  465. */
  466. public static function helper($name)
  467. {
  468. if (strpos($name, '/') === false) {
  469. $name .= '/data';
  470. }
  471. $registryKey = '_helper/' . $name;
  472. if (!self::registry($registryKey)) {
  473. $helperClass = self::getConfig()->getHelperClassName($name);
  474. self::register($registryKey, new $helperClass);
  475. }
  476. return self::registry($registryKey);
  477. }
  478. /**
  479. * Return new exception by module to be thrown
  480. *
  481. * @param string $module
  482. * @param string $message
  483. * @param integer $code
  484. * @return Mage_Core_Exception
  485. */
  486. public static function exception($module = 'Mage_Core', $message = '', $code = 0)
  487. {
  488. $className = $module.'_Exception';
  489. return new $className($message, $code);
  490. }
  491. /**
  492. * Throw Exception
  493. *
  494. * @param string $message
  495. * @param string $messageStorage
  496. */
  497. public static function throwException($message, $messageStorage = null)
  498. {
  499. if ($messageStorage && ($storage = self::getSingleton($messageStorage))) {
  500. $storage->addError($message);
  501. }
  502. throw new Mage_Core_Exception($message);
  503. }
  504. /**
  505. * Get initialized application object.
  506. *
  507. * @param string $code
  508. * @param string $type
  509. * @param string|array $options
  510. * @return Mage_Core_Model_App
  511. */
  512. public static function app($code = '', $type = 'store', $options = array())
  513. {
  514. if (null === self::$_app) {
  515. self::$_app = new Mage_Core_Model_App();
  516. self::setRoot();
  517. self::$_events = new Varien_Event_Collection();
  518. self::$_config = new Mage_Core_Model_Config();
  519. Varien_Profiler::start('self::app::init');
  520. self::$_app->init($code, $type, $options);
  521. Varien_Profiler::stop('self::app::init');
  522. self::$_app->loadAreaPart(Mage_Core_Model_App_Area::AREA_GLOBAL, Mage_Core_Model_App_Area::PART_EVENTS);
  523. }
  524. return self::$_app;
  525. }
  526. /**
  527. * @static
  528. * @param string $code
  529. * @param string $type
  530. * @param array $options
  531. * @param string|array $modules
  532. */
  533. public static function init($code = '', $type = 'store', $options = array(), $modules = array())
  534. {
  535. try {
  536. self::setRoot();
  537. self::$_app = new Mage_Core_Model_App();
  538. self::$_config = new Mage_Core_Model_Config();
  539. if (!empty($modules)) {
  540. self::$_app->initSpecified($code, $type, $options, $modules);
  541. } else {
  542. self::$_app->init($code, $type, $options);
  543. }
  544. } catch (Mage_Core_Model_Session_Exception $e) {
  545. header('Location: ' . self::getBaseUrl());
  546. die;
  547. } catch (Mage_Core_Model_Store_Exception $e) {
  548. require_once(self::getBaseDir() . DS . 'errors' . DS . '404.php');
  549. die;
  550. } catch (Exception $e) {
  551. self::printException($e);
  552. die;
  553. }
  554. }
  555. /**
  556. * Front end main entry point
  557. *
  558. * @param string $code
  559. * @param string $type
  560. * @param string|array $options
  561. */
  562. public static function run($code = '', $type = 'store', $options=array())
  563. {
  564. try {
  565. Varien_Profiler::start('mage');
  566. self::setRoot();
  567. self::$_app = new Mage_Core_Model_App();
  568. self::$_events = new Varien_Event_Collection();
  569. self::$_config = new Mage_Core_Model_Config();
  570. self::$_app->run(array(
  571. 'scope_code' => $code,
  572. 'scope_type' => $type,
  573. 'options' => $options,
  574. ));
  575. Varien_Profiler::stop('mage');
  576. } catch (Mage_Core_Model_Session_Exception $e) {
  577. header('Location: ' . self::getBaseUrl());
  578. die();
  579. } catch (Mage_Core_Model_Store_Exception $e) {
  580. require_once(self::getBaseDir() . DS . 'errors' . DS . '404.php');
  581. die();
  582. } catch (Exception $e) {
  583. if (self::isInstalled() || self::$_isDownloader) {
  584. self::printException($e);
  585. exit();
  586. }
  587. try {
  588. self::dispatchEvent('mage_run_exception', array('exception' => $e));
  589. if (!headers_sent()) {
  590. header('Location:' . self::getUrl('install'));
  591. } else {
  592. self::printException($e);
  593. }
  594. } catch (Exception $ne) {
  595. self::printException($ne, $e->getMessage());
  596. }
  597. }
  598. }
  599. /**
  600. * Retrieve application installation flag
  601. *
  602. * @param string|array $options
  603. * @return bool
  604. */
  605. public static function isInstalled($options = array())
  606. {
  607. if (self::$_isInstalled === null) {
  608. self::setRoot();
  609. if (is_string($options)) {
  610. $options = array('etc_dir' => $options);
  611. }
  612. $etcDir = 'etc';
  613. if (!empty($options['etc_dir'])) {
  614. $etcDir = $options['etc_dir'];
  615. }
  616. $localConfigFile = self::getRoot() . DS . $etcDir . DS . 'local.xml';
  617. self::$_isInstalled = false;
  618. if (is_readable($localConfigFile)) {
  619. $localConfig = simplexml_load_file($localConfigFile);
  620. date_default_timezone_set('UTC');
  621. if (($date = $localConfig->global->install->date) && strtotime($date)) {
  622. self::$_isInstalled = true;
  623. }
  624. }
  625. }
  626. return self::$_isInstalled;
  627. }
  628. /**
  629. * log facility (??)
  630. *
  631. * @param string $message
  632. * @param integer $level
  633. * @param string $file
  634. * @param bool $forceLog
  635. */
  636. public static function log($message, $level = null, $file = '', $forceLog = false)
  637. {
  638. if (!self::getConfig()) {
  639. return;
  640. }
  641. try {
  642. $logActive = self::getStoreConfig('dev/log/active');
  643. if (empty($file)) {
  644. $file = self::getStoreConfig('dev/log/file');
  645. }
  646. }
  647. catch (Exception $e) {
  648. $logActive = true;
  649. }
  650. if (!self::$_isDeveloperMode && !$logActive && !$forceLog) {
  651. return;
  652. }
  653. static $loggers = array();
  654. $level = is_null($level) ? Zend_Log::DEBUG : $level;
  655. $file = empty($file) ? 'system.log' : $file;
  656. try {
  657. if (!isset($loggers[$file])) {
  658. $logFile = self::getBaseDir('var') . DS . 'log' . DS . $file;
  659. if (!is_dir(self::getBaseDir('var').DS.'log')) {
  660. mkdir(self::getBaseDir('var').DS.'log', 0777);
  661. }
  662. if (!file_exists($logFile)) {
  663. file_put_contents($logFile, '');
  664. chmod($logFile, 0777);
  665. }
  666. $format = '%timestamp% %priorityName% (%priority%): %message%' . PHP_EOL;
  667. $formatter = new Zend_Log_Formatter_Simple($format);
  668. $writerModel = (string)self::getConfig()->getNode('global/log/core/writer_model');
  669. if (!self::$_app || !$writerModel) {
  670. $writer = new Zend_Log_Writer_Stream($logFile);
  671. }
  672. else {
  673. $writer = new $writerModel($logFile);
  674. }
  675. $writer->setFormatter($formatter);
  676. $loggers[$file] = new Zend_Log($writer);
  677. }
  678. if (is_array($message) || is_object($message)) {
  679. $message = print_r($message, true);
  680. }
  681. $loggers[$file]->log($message, $level);
  682. }
  683. catch (Exception $e) {
  684. }
  685. }
  686. /**
  687. * Write exception to log
  688. *
  689. * @param Exception $e
  690. */
  691. public static function logException(Exception $e)
  692. {
  693. if (!self::getConfig()) {
  694. return;
  695. }
  696. $file = self::getStoreConfig('dev/log/exception_file');
  697. self::log("\n" . $e->__toString(), Zend_Log::ERR, $file);
  698. }
  699. /**
  700. * Set enabled developer mode
  701. *
  702. * @param bool $mode
  703. * @return bool
  704. */
  705. public static function setIsDeveloperMode($mode)
  706. {
  707. self::$_isDeveloperMode = (bool)$mode;
  708. return self::$_isDeveloperMode;
  709. }
  710. /**
  711. * Retrieve enabled developer mode
  712. *
  713. * @return bool
  714. */
  715. public static function getIsDeveloperMode()
  716. {
  717. return self::$_isDeveloperMode;
  718. }
  719. /**
  720. * Display exception
  721. *
  722. * @param Exception $e
  723. */
  724. public static function printException(Exception $e, $extra = '')
  725. {
  726. if (self::$_isDeveloperMode) {
  727. print '<pre>';
  728. if (!empty($extra)) {
  729. print $extra . "\n\n";
  730. }
  731. print $e->getMessage() . "\n\n";
  732. print $e->getTraceAsString();
  733. print '</pre>';
  734. } else {
  735. $reportData = array(
  736. !empty($extra) ? $extra . "\n\n" : '' . $e->getMessage(),
  737. $e->getTraceAsString()
  738. );
  739. // retrieve server data
  740. if (isset($_SERVER)) {
  741. if (isset($_SERVER['REQUEST_URI'])) {
  742. $reportData['url'] = $_SERVER['REQUEST_URI'];
  743. }
  744. if (isset($_SERVER['SCRIPT_NAME'])) {
  745. $reportData['script_name'] = $_SERVER['SCRIPT_NAME'];
  746. }
  747. }
  748. // attempt to specify store as a skin
  749. try {
  750. $storeCode = self::app()->getStore()->getCode();
  751. $reportData['skin'] = $storeCode;
  752. }
  753. catch (Exception $e) {}
  754. require_once(self::getBaseDir() . DS . 'errors' . DS . 'report.php');
  755. }
  756. die();
  757. }
  758. /**
  759. * Define system folder directory url by virtue of running script directory name
  760. * Try to find requested folder by shifting to domain root directory
  761. *
  762. * @param string $folder
  763. * @param boolean $exitIfNot
  764. * @return string
  765. */
  766. public static function getScriptSystemUrl($folder, $exitIfNot = false)
  767. {
  768. $runDirUrl = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/');
  769. $runDir = rtrim(dirname($_SERVER['SCRIPT_FILENAME']), DS);
  770. $baseUrl = null;
  771. if (is_dir($runDir.'/'.$folder)) {
  772. $baseUrl = str_replace(DS, '/', $runDirUrl);
  773. } else {
  774. $runDirUrlArray = explode('/', $runDirUrl);
  775. $runDirArray = explode('/', $runDir);
  776. $count = count($runDirArray);
  777. for ($i=0; $i < $count; $i++) {
  778. array_pop($runDirUrlArray);
  779. array_pop($runDirArray);
  780. $_runDir = implode('/', $runDirArray);
  781. if (!empty($_runDir)) {
  782. $_runDir .= '/';
  783. }
  784. if (is_dir($_runDir.$folder)) {
  785. $_runDirUrl = implode('/', $runDirUrlArray);
  786. $baseUrl = str_replace(DS, '/', $_runDirUrl);
  787. break;
  788. }
  789. }
  790. }
  791. if (is_null($baseUrl)) {
  792. $errorMessage = "Unable detect system directory: $folder";
  793. if ($exitIfNot) {
  794. // exit because of infinity loop
  795. exit($errorMessage);
  796. } else {
  797. self::printException(new Exception(), $errorMessage);
  798. }
  799. }
  800. return $baseUrl;
  801. }
  802. /**
  803. * Set is downloader flag
  804. *
  805. * @param bool $flag
  806. */
  807. public static function setIsDownloader($flag = true)
  808. {
  809. self::$_isDownloader = $flag;
  810. }
  811. }