PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/Devblocks.class.php

https://github.com/Hildy/devblocks
PHP | 1005 lines | 570 code | 178 blank | 257 comment | 100 complexity | 590d5aae378d20b9847d6c27b32c7deb MD5 | raw file
  1. <?php
  2. include_once(DEVBLOCKS_PATH . "api/Engine.php");
  3. include_once(DEVBLOCKS_PATH . "api/Model.php");
  4. include_once(DEVBLOCKS_PATH . "api/DAO.php");
  5. include_once(DEVBLOCKS_PATH . "api/Extension.php");
  6. define('PLATFORM_BUILD',305);
  7. /**
  8. * @defgroup core Devblocks Framework Core
  9. * Core data structures of the framework
  10. */
  11. /**
  12. * @defgroup plugin Devblocks Framework Plugins
  13. * Components for plugin/extensions
  14. */
  15. /**
  16. * @defgroup services Devblocks Framework Services
  17. * Services provided by the framework
  18. */
  19. /**
  20. * A platform container for plugin/extension registries.
  21. *
  22. * @ingroup core
  23. * @author Jeff Standen <jeff@webgroupmedia.com>
  24. */
  25. class DevblocksPlatform extends DevblocksEngine {
  26. const CACHE_ACL = 'devblocks_acl';
  27. const CACHE_EVENT_POINTS = 'devblocks_event_points';
  28. const CACHE_EVENTS = 'devblocks_events';
  29. const CACHE_EXTENSIONS = 'devblocks_extensions';
  30. const CACHE_PLUGINS = 'devblocks_plugins';
  31. const CACHE_POINTS = 'devblocks_points';
  32. const CACHE_SETTINGS = 'devblocks_settings';
  33. const CACHE_TABLES = 'devblocks_tables';
  34. const CACHE_TAG_TRANSLATIONS = 'devblocks_translations';
  35. static private $extensionDelegate = null;
  36. static private $start_time = 0;
  37. static private $start_memory = 0;
  38. static private $start_peak_memory = 0;
  39. static private $locale = 'en_US';
  40. private function __construct() {}
  41. /**
  42. * @param mixed $var
  43. * @param string $cast
  44. * @param mixed $default
  45. * @return mixed
  46. */
  47. static function importGPC($var,$cast=null,$default=null) {
  48. if(!is_null($var)) {
  49. if(is_string($var)) {
  50. $var = get_magic_quotes_gpc() ? stripslashes($var) : $var;
  51. } elseif(is_array($var)) {
  52. foreach($var as $k => $v) {
  53. $var[$k] = get_magic_quotes_gpc() ? stripslashes($v) : $v;
  54. }
  55. }
  56. } elseif (is_null($var) && !is_null($default)) {
  57. $var = $default;
  58. }
  59. if(!is_null($cast))
  60. @settype($var, $cast);
  61. return $var;
  62. }
  63. /**
  64. * Returns a string as a regexp.
  65. * "*bob" returns "/(.*?)bob/".
  66. */
  67. static function parseStringAsRegExp($string) {
  68. $pattern = str_replace(array('*'),'__any__', $string);
  69. $pattern = sprintf("/%s/i",str_replace(array('__any__'),'(.*?)', preg_quote($pattern)));
  70. return $pattern;
  71. }
  72. static function parseCrlfString($string) {
  73. $parts = preg_split("/[\r\n]/", $string);
  74. // Remove any empty tokens
  75. foreach($parts as $idx => $part) {
  76. $parts[$idx] = trim($part);
  77. if(0 == strlen($parts[$idx]))
  78. unset($parts[$idx]);
  79. }
  80. return $parts;
  81. }
  82. /**
  83. * Returns a string as alphanumerics delimited by underscores.
  84. * For example: "Devs: 1000 Ways to Improve Sales" becomes
  85. * "devs_1000_ways_to_improve_sales", which is suitable for
  86. * displaying in a URL of a blog, faq, etc.
  87. *
  88. * @param string $str
  89. * @return string
  90. */
  91. static function getStringAsURI($str) {
  92. $str = strtolower($str);
  93. // turn non [a-z, 0-9, _] into whitespace
  94. $str = preg_replace("/[^0-9a-z]/",' ',$str);
  95. // condense whitespace to a single underscore
  96. $str = preg_replace('/\s\s+/', ' ', $str);
  97. // replace spaces with underscore
  98. $str = str_replace(' ','_',$str);
  99. // remove a leading/trailing underscores
  100. $str = trim($str, '_');
  101. return $str;
  102. }
  103. /**
  104. * Takes a comma-separated value string and returns an array of tokens.
  105. * [TODO] Move to a FormHelper service?
  106. *
  107. * @param string $string
  108. * @return array
  109. */
  110. static function parseCsvString($string) {
  111. $tokens = explode(',', $string);
  112. if(!is_array($tokens))
  113. return array();
  114. foreach($tokens as $k => $v) {
  115. $tokens[$k] = trim($v);
  116. if(0==strlen($tokens[$k]))
  117. unset($tokens[$k]);
  118. }
  119. return $tokens;
  120. }
  121. /**
  122. * Clears any platform-level plugin caches.
  123. *
  124. */
  125. static function clearCache() {
  126. $cache = self::getCacheService(); /* @var $cache Zend_Cache_Core */
  127. $cache->remove(self::CACHE_ACL);
  128. $cache->remove(self::CACHE_PLUGINS);
  129. $cache->remove(self::CACHE_EVENT_POINTS);
  130. $cache->remove(self::CACHE_EVENTS);
  131. $cache->remove(self::CACHE_EXTENSIONS);
  132. $cache->remove(self::CACHE_POINTS);
  133. $cache->remove(self::CACHE_SETTINGS);
  134. $cache->remove(self::CACHE_TABLES);
  135. $cache->remove(_DevblocksClassLoadManager::CACHE_CLASS_MAP);
  136. // Clear all locale caches
  137. $langs = DAO_Translation::getDefinedLangCodes();
  138. if(is_array($langs) && !empty($langs))
  139. foreach($langs as $lang_code => $lang_name) {
  140. $cache->remove(self::CACHE_TAG_TRANSLATIONS . '_' . $lang_code);
  141. }
  142. // Recache plugins
  143. self::getPluginRegistry();
  144. self::getExtensionRegistry();
  145. }
  146. public static function loadClass($className) {
  147. $classloader = self::getClassLoaderService();
  148. return $classloader->loadClass($className);
  149. }
  150. public static function registerClasses($file,$classes=array()) {
  151. $classloader = self::getClassLoaderService();
  152. return $classloader->registerClasses($file,$classes);
  153. }
  154. public static function getStartTime() {
  155. return self::$start_time;
  156. }
  157. public static function getStartMemory() {
  158. return self::$start_memory;
  159. }
  160. public static function getStartPeakMemory() {
  161. return self::$start_peak_memory;
  162. }
  163. /**
  164. * Checks whether the active database has any tables.
  165. *
  166. * @return boolean
  167. */
  168. static function isDatabaseEmpty() {
  169. $tables = self::getDatabaseTables();
  170. return empty($tables);
  171. }
  172. static function getDatabaseTables() {
  173. $cache = self::getCacheService();
  174. $tables = array();
  175. if(null === ($tables = $cache->load(self::CACHE_TABLES))) {
  176. $db = self::getDatabaseService(); /* @var $db ADODB_Connection */
  177. // Make sure the database connection is valid or error out.
  178. if(is_null($db) || !$db->IsConnected())
  179. return array();
  180. $tables = $db->MetaTables('TABLE',false);
  181. $cache->save($tables, self::CACHE_TABLES);
  182. }
  183. return $tables;
  184. }
  185. /**
  186. * Checks to see if the application needs to patch
  187. *
  188. * @return boolean
  189. */
  190. static function versionConsistencyCheck() {
  191. $cache = DevblocksPlatform::getCacheService(); /* @var Zend_Cache_Core $cache */
  192. if(null === ($build_cache = $cache->load("devblocks_app_build"))
  193. || $build_cache != APP_BUILD) {
  194. // If build changed, clear cache regardless of patch status
  195. // [TODO] We need to find a nicer way to not clear a shared memcached cluster when only one desk needs to
  196. $cache = DevblocksPlatform::getCacheService(); /* @var $cache Zend_Cache_Core */
  197. $cache->clean('all');
  198. // Re-read manifests
  199. DevblocksPlatform::readPlugins();
  200. if(self::_needsToPatch()) {
  201. return false; // the update script will handle new caches
  202. } else {
  203. $cache->save(APP_BUILD, "devblocks_app_build");
  204. DAO_Translation::reloadPluginStrings(); // reload strings even without DB changes
  205. return true;
  206. }
  207. }
  208. return true;
  209. }
  210. /**
  211. * Enter description here...
  212. *
  213. * @return boolean
  214. */
  215. static private function _needsToPatch() {
  216. $plugins = DevblocksPlatform::getPluginRegistry();
  217. $containers = DevblocksPlatform::getExtensions("devblocks.patch.container", true, true);
  218. // [JAS]: Devblocks
  219. array_unshift($containers, new PlatformPatchContainer());
  220. foreach($containers as $container) { /* @var $container DevblocksPatchContainerExtension */
  221. foreach($container->getPatches() as $patch) { /* @var $patch DevblocksPatch */
  222. if(!$patch->hasRun()) {
  223. // echo "Need to run a patch: ",$patch->getPluginId(),$patch->getRevision();
  224. return true;
  225. }
  226. }
  227. }
  228. // echo "Don't need to run any patches.";
  229. return false;
  230. }
  231. /**
  232. * Runs patches for all active plugins
  233. *
  234. * @return boolean
  235. */
  236. static function runPluginPatches() {
  237. // Log out all sessions before patching
  238. $db = DevblocksPlatform::getDatabaseService();
  239. $db->Execute(sprintf("DELETE FROM %s_session", APP_DB_PREFIX));
  240. $patchMgr = DevblocksPlatform::getPatchService();
  241. // echo "Patching platform... ";
  242. // [JAS]: Run our overloaded container for the platform
  243. $patchMgr->registerPatchContainer(new PlatformPatchContainer());
  244. // Clean script
  245. if(!$patchMgr->run()) {
  246. return false;
  247. } else { // success
  248. // Read in plugin information from the filesystem to the database
  249. DevblocksPlatform::readPlugins();
  250. $plugins = DevblocksPlatform::getPluginRegistry();
  251. // DevblocksPlatform::clearCache();
  252. // Run enabled plugin patches
  253. $patches = DevblocksPlatform::getExtensions("devblocks.patch.container",false,true);
  254. if(is_array($patches))
  255. foreach($patches as $patch_manifest) { /* @var $patch_manifest DevblocksExtensionManifest */
  256. if(null != ($container = $patch_manifest->createInstance())) { /* @var $container DevblocksPatchContainerExtension */
  257. if(!is_null($container)) {
  258. $patchMgr->registerPatchContainer($container);
  259. }
  260. }
  261. }
  262. // echo "Patching plugins... ";
  263. if(!$patchMgr->run()) { // fail
  264. return false;
  265. }
  266. // echo "done!<br>";
  267. $cache = self::getCacheService();
  268. $cache->save(APP_BUILD, "devblocks_app_build");
  269. return true;
  270. }
  271. }
  272. /**
  273. * Returns the list of extensions on a given extension point.
  274. *
  275. * @static
  276. * @param string $point
  277. * @return DevblocksExtensionManifest[]
  278. */
  279. static function getExtensions($point,$as_instances=false, $ignore_acl=false) {
  280. $results = array();
  281. $extensions = DevblocksPlatform::getExtensionRegistry($ignore_acl);
  282. if(is_array($extensions))
  283. foreach($extensions as $extension) { /* @var $extension DevblocksExtensionManifest */
  284. if(0 == strcasecmp($extension->point,$point)) {
  285. $results[$extension->id] = ($as_instances) ? $extension->createInstance() : $extension;
  286. }
  287. }
  288. return $results;
  289. }
  290. /**
  291. * Returns the manifest of a given extension ID.
  292. *
  293. * @static
  294. * @param string $extension_id
  295. * @param boolean $as_instance
  296. * @return DevblocksExtensionManifest
  297. */
  298. static function getExtension($extension_id, $as_instance=false, $ignore_acl=false) {
  299. $result = null;
  300. $extensions = DevblocksPlatform::getExtensionRegistry($ignore_acl);
  301. if(is_array($extensions))
  302. foreach($extensions as $extension) { /* @var $extension DevblocksExtensionManifest */
  303. if(0 == strcasecmp($extension->id,$extension_id)) {
  304. $result = $extension;
  305. break;
  306. }
  307. }
  308. if($as_instance && !is_null($result)) {
  309. return $result->createInstance();
  310. }
  311. return $result;
  312. }
  313. // static function getExtensionPoints() {
  314. // $cache = self::getCacheService();
  315. // if(null !== ($points = $cache->load(self::CACHE_POINTS)))
  316. // return $points;
  317. //
  318. // $extensions = DevblocksPlatform::getExtensionRegistry();
  319. // foreach($extensions as $extension) { /* @var $extension DevblocksExtensionManifest */
  320. // $point = $extension->point;
  321. // if(!isset($points[$point])) {
  322. // $p = new DevblocksExtensionPoint();
  323. // $p->id = $point;
  324. // $points[$point] = $p;
  325. // }
  326. //
  327. // $points[$point]->extensions[$extension->id] = $extension;
  328. // }
  329. //
  330. // $cache->save($points, self::CACHE_POINTS);
  331. // return $points;
  332. // }
  333. /**
  334. * Returns an array of all contributed extension manifests.
  335. *
  336. * @static
  337. * @return DevblocksExtensionManifest[]
  338. */
  339. static function getExtensionRegistry($ignore_acl=false) {
  340. $cache = self::getCacheService();
  341. if(null === ($extensions = $cache->load(self::CACHE_EXTENSIONS))) {
  342. $db = DevblocksPlatform::getDatabaseService();
  343. if(is_null($db)) return;
  344. $prefix = (APP_DB_PREFIX != '') ? APP_DB_PREFIX.'_' : ''; // [TODO] Cleanup
  345. $sql = sprintf("SELECT e.id , e.plugin_id, e.point, e.pos, e.name , e.file , e.class, e.params ".
  346. "FROM %sextension e ".
  347. "INNER JOIN %splugin p ON (e.plugin_id=p.id) ".
  348. "WHERE p.enabled = 1 ".
  349. "ORDER BY e.plugin_id ASC, e.pos ASC",
  350. $prefix,
  351. $prefix
  352. );
  353. $rs = $db->Execute($sql); /* @var $rs ADORecordSet */
  354. if(is_a($rs,'ADORecordSet'))
  355. while(!$rs->EOF) {
  356. $extension = new DevblocksExtensionManifest();
  357. $extension->id = $rs->fields['id'];
  358. $extension->plugin_id = $rs->fields['plugin_id'];
  359. $extension->point = $rs->fields['point'];
  360. $extension->name = $rs->fields['name'];
  361. $extension->file = $rs->fields['file'];
  362. $extension->class = $rs->fields['class'];
  363. $extension->params = @unserialize($rs->fields['params']);
  364. if(empty($extension->params))
  365. $extension->params = array();
  366. $extensions[$extension->id] = $extension;
  367. $rs->MoveNext();
  368. }
  369. $cache->save($extensions, self::CACHE_EXTENSIONS);
  370. }
  371. // Check with an extension delegate if we have one
  372. if(!$ignore_acl && class_exists(self::$extensionDelegate) && method_exists('DevblocksExtensionDelegate','shouldLoadExtension')) {
  373. if(is_array($extensions))
  374. foreach($extensions as $id => $extension) {
  375. // Ask the delegate if we should load the extension
  376. if(!call_user_func(array(self::$extensionDelegate,'shouldLoadExtension'),$extension))
  377. unset($extensions[$id]);
  378. }
  379. }
  380. return $extensions;
  381. }
  382. /**
  383. * @return DevblocksEventPoint[]
  384. */
  385. static function getEventPointRegistry() {
  386. $cache = self::getCacheService();
  387. if(null !== ($events = $cache->load(self::CACHE_EVENT_POINTS)))
  388. return $events;
  389. $events = array();
  390. $plugins = self::getPluginRegistry();
  391. // [JAS]: Event point hashing/caching
  392. if(is_array($plugins))
  393. foreach($plugins as $plugin) { /* @var $plugin DevblocksPluginManifest */
  394. $events = array_merge($events,$plugin->event_points);
  395. }
  396. $cache->save($events, self::CACHE_EVENT_POINTS);
  397. return $events;
  398. }
  399. /**
  400. * @return DevblocksAclPrivilege[]
  401. */
  402. static function getAclRegistry() {
  403. $cache = self::getCacheService();
  404. if(null !== ($acl = $cache->load(self::CACHE_ACL)))
  405. return $acl;
  406. $acl = array();
  407. $db = DevblocksPlatform::getDatabaseService();
  408. if(is_null($db)) return;
  409. //$plugins = self::getPluginRegistry();
  410. $prefix = (APP_DB_PREFIX != '') ? APP_DB_PREFIX.'_' : ''; // [TODO] Cleanup
  411. $sql = sprintf("SELECT a.id, a.plugin_id, a.label ".
  412. "FROM %sacl a ".
  413. "INNER JOIN %splugin p ON (a.plugin_id=p.id) ".
  414. "WHERE p.enabled = 1 ".
  415. "ORDER BY a.plugin_id, a.id ASC",
  416. $prefix,
  417. $prefix
  418. );
  419. $rs = $db->Execute($sql); /* @var $rs ADORecordSet */
  420. if(is_a($rs,'ADORecordSet'))
  421. while(!$rs->EOF) {
  422. $priv = new DevblocksAclPrivilege();
  423. $priv->id = $rs->fields['id'];
  424. $priv->plugin_id = $rs->fields['plugin_id'];
  425. $priv->label = $rs->fields['label'];
  426. $acl[$priv->id] = $priv;
  427. $rs->MoveNext();
  428. }
  429. $cache->save($acl, self::CACHE_ACL);
  430. return $acl;
  431. }
  432. static function getEventRegistry() {
  433. $cache = self::getCacheService();
  434. if(null !== ($events = $cache->load(self::CACHE_EVENTS)))
  435. return $events;
  436. $extensions = self::getExtensions('devblocks.listener.event',false,true);
  437. $events = array('*');
  438. // [JAS]: Event point hashing/caching
  439. if(is_array($extensions))
  440. foreach($extensions as $extension) { /* @var $extension DevblocksExtensionManifest */
  441. @$evts = $extension->params['events'][0];
  442. // Global listeners (every point)
  443. if(empty($evts) && !is_array($evts)) {
  444. $events['*'][] = $extension->id;
  445. continue;
  446. }
  447. if(is_array($evts))
  448. foreach(array_keys($evts) as $evt) {
  449. $events[$evt][] = $extension->id;
  450. }
  451. }
  452. $cache->save($events, self::CACHE_EVENTS);
  453. return $events;
  454. }
  455. /**
  456. * Returns an array of all contributed plugin manifests.
  457. *
  458. * @static
  459. * @return DevblocksPluginManifest[]
  460. */
  461. static function getPluginRegistry() {
  462. $cache = self::getCacheService();
  463. if(null !== ($plugins = $cache->load(self::CACHE_PLUGINS)))
  464. return $plugins;
  465. $db = DevblocksPlatform::getDatabaseService();
  466. if(is_null($db)) return;
  467. $prefix = (APP_DB_PREFIX != '') ? APP_DB_PREFIX.'_' : ''; // [TODO] Cleanup
  468. $sql = sprintf("SELECT p.id, p.enabled, p.name, p.description, p.author, p.revision, p.link, p.dir, p.templates_json ".
  469. "FROM %splugin p ".
  470. "ORDER BY p.enabled DESC, p.name ASC ",
  471. $prefix
  472. );
  473. $rs = $db->Execute($sql); /* @var $rs ADORecordSet */
  474. if(is_a($rs,'ADORecordSet'))
  475. while(!$rs->EOF) {
  476. $plugin = new DevblocksPluginManifest();
  477. @$plugin->id = $rs->fields['id'];
  478. @$plugin->enabled = intval($rs->fields['enabled']);
  479. @$plugin->name = $rs->fields['name'];
  480. @$plugin->description = $rs->fields['description'];
  481. @$plugin->author = $rs->fields['author'];
  482. @$plugin->revision = intval($rs->fields['revision']);
  483. @$plugin->link = $rs->fields['link'];
  484. @$plugin->dir = $rs->fields['dir'];
  485. // JSON decode templates
  486. if(null != ($templates_json = $rs->Fields('templates_json'))) {
  487. $plugin->templates = json_decode($templates_json, true);
  488. }
  489. if(file_exists(APP_PATH . DIRECTORY_SEPARATOR . $plugin->dir . DIRECTORY_SEPARATOR . 'plugin.xml')) {
  490. $plugins[$plugin->id] = $plugin;
  491. }
  492. $rs->MoveNext();
  493. }
  494. $sql = sprintf("SELECT p.id, p.name, p.params, p.plugin_id ".
  495. "FROM %sevent_point p ",
  496. $prefix
  497. );
  498. $rs = $db->Execute($sql); /* @var $rs ADORecordSet */
  499. if(is_a($rs,'ADORecordSet'))
  500. while(!$rs->EOF) {
  501. $point = new DevblocksEventPoint();
  502. $point->id = $rs->fields['id'];
  503. $point->name = $rs->fields['name'];
  504. $point->plugin_id = $rs->fields['plugin_id'];
  505. $params = $rs->fields['params'];
  506. $point->params = !empty($params) ? unserialize($params) : array();
  507. if(isset($plugins[$point->plugin_id])) {
  508. $plugins[$point->plugin_id]->event_points[$point->id] = $point;
  509. }
  510. $rs->MoveNext();
  511. }
  512. $cache->save($plugins, self::CACHE_PLUGINS);
  513. return $plugins;
  514. }
  515. /**
  516. * Enter description here...
  517. *
  518. * @param string $id
  519. * @return DevblocksPluginManifest
  520. */
  521. static function getPlugin($id) {
  522. $plugins = DevblocksPlatform::getPluginRegistry();
  523. if(isset($plugins[$id]))
  524. return $plugins[$id];
  525. return null;
  526. }
  527. /**
  528. * Reads and caches manifests from the features + plugins directories.
  529. *
  530. * @static
  531. * @return DevblocksPluginManifest[]
  532. */
  533. static function readPlugins() {
  534. $scan_dirs = array(
  535. 'features',
  536. 'storage/plugins',
  537. );
  538. $plugins = array();
  539. if(is_array($scan_dirs))
  540. foreach($scan_dirs as $scan_dir) {
  541. $scan_path = APP_PATH . '/' . $scan_dir;
  542. if (is_dir($scan_path)) {
  543. if ($dh = opendir($scan_path)) {
  544. while (($file = readdir($dh)) !== false) {
  545. if($file=="." || $file == "..")
  546. continue;
  547. $plugin_path = $scan_path . '/' . $file;
  548. $rel_path = $scan_dir . '/' . $file;
  549. if(is_dir($plugin_path) && file_exists($plugin_path.'/plugin.xml')) {
  550. $manifest = self::_readPluginManifest($rel_path); /* @var $manifest DevblocksPluginManifest */
  551. if(null != $manifest) {
  552. $plugins[] = $manifest;
  553. }
  554. }
  555. }
  556. closedir($dh);
  557. }
  558. }
  559. }
  560. // [TODO] Instance the plugins in dependency order
  561. DAO_Platform::cleanupPluginTables();
  562. DevblocksPlatform::clearCache();
  563. return $plugins;
  564. }
  565. /**
  566. * @return _DevblocksPluginSettingsManager
  567. */
  568. static function getPluginSettingsService() {
  569. return _DevblocksPluginSettingsManager::getInstance();
  570. }
  571. /**
  572. * @return Zend_Log
  573. */
  574. static function getConsoleLog() {
  575. return _DevblocksLogManager::getConsoleLog();
  576. }
  577. /**
  578. * @return _DevblocksCacheManager
  579. */
  580. static function getCacheService() {
  581. return _DevblocksCacheManager::getInstance();
  582. }
  583. /**
  584. * Enter description here...
  585. *
  586. * @return ADOConnection
  587. */
  588. static function getDatabaseService() {
  589. return _DevblocksDatabaseManager::getInstance();
  590. }
  591. /**
  592. * @return _DevblocksPatchManager
  593. */
  594. static function getPatchService() {
  595. return _DevblocksPatchManager::getInstance();
  596. }
  597. /**
  598. * @return _DevblocksUrlManager
  599. */
  600. static function getUrlService() {
  601. return _DevblocksUrlManager::getInstance();
  602. }
  603. /**
  604. * @return _DevblocksEmailManager
  605. */
  606. static function getMailService() {
  607. return _DevblocksEmailManager::getInstance();
  608. }
  609. /**
  610. * @return _DevblocksEventManager
  611. */
  612. static function getEventService() {
  613. return _DevblocksEventManager::getInstance();
  614. }
  615. /**
  616. * @return DevblocksProxy
  617. */
  618. static function getProxyService() {
  619. return DevblocksProxy::getProxy();
  620. }
  621. /**
  622. * @return _DevblocksClassLoadManager
  623. */
  624. static function getClassLoaderService() {
  625. return _DevblocksClassLoadManager::getInstance();
  626. }
  627. /**
  628. * @return _DevblocksSessionManager
  629. */
  630. static function getSessionService() {
  631. return _DevblocksSessionManager::getInstance();
  632. }
  633. /**
  634. * @return Smarty
  635. */
  636. static function getTemplateService() {
  637. return _DevblocksTemplateManager::getInstance();
  638. }
  639. /**
  640. *
  641. * @param string $set
  642. * @return DevblocksTemplate[]
  643. */
  644. static function getTemplates($set=null) {
  645. $templates = array();
  646. $plugins = self::getPluginRegistry();
  647. if(is_array($plugins))
  648. foreach($plugins as $plugin) {
  649. if(is_array($plugin->templates))
  650. foreach($plugin->templates as $tpl) {
  651. if(null === $set || 0 == strcasecmp($set, $tpl['set'])) {
  652. $template = new DevblocksTemplate();
  653. $template->plugin_id = $tpl['plugin_id'];
  654. $template->set = $tpl['set'];
  655. $template->path = $tpl['path'];
  656. $templates[] = $template;
  657. }
  658. }
  659. }
  660. return $templates;
  661. }
  662. /**
  663. * @return _DevblocksTemplateBuilder
  664. */
  665. static function getTemplateBuilder() {
  666. return _DevblocksTemplateBuilder::getInstance();
  667. }
  668. /**
  669. * @return _DevblocksDateManager
  670. */
  671. static function getDateService($datestamp=null) {
  672. return _DevblocksDateManager::getInstance();
  673. }
  674. static function setLocale($locale) {
  675. @setlocale(LC_ALL, $locale);
  676. self::$locale = $locale;
  677. }
  678. static function getLocale() {
  679. if(!empty(self::$locale))
  680. return self::$locale;
  681. return 'en_US';
  682. }
  683. /**
  684. * @return _DevblocksTranslationManager
  685. */
  686. static function getTranslationService() {
  687. $locale = DevblocksPlatform::getLocale();
  688. if(Zend_Registry::isRegistered('Devblocks:getTranslationService:'.$locale)) {
  689. return Zend_Registry::get('Devblocks:getTranslationService:'.$locale);
  690. }
  691. $cache = self::getCacheService();
  692. if(null === ($map = $cache->load(self::CACHE_TAG_TRANSLATIONS.'_'.$locale))) { /* @var $cache Zend_Cache_Core */
  693. $map = array();
  694. $map_en = DAO_Translation::getMapByLang('en_US');
  695. if(0 != strcasecmp('en_US', $locale))
  696. $map_loc = DAO_Translation::getMapByLang($locale);
  697. // Loop through the English string objects
  698. if(is_array($map_en))
  699. foreach($map_en as $string_id => $obj_string_en) {
  700. $string = '';
  701. // If we have a locale to check
  702. if(isset($map_loc) && is_array($map_loc)) {
  703. @$obj_string_loc = $map_loc[$string_id];
  704. @$string =
  705. (!empty($obj_string_loc->string_override))
  706. ? $obj_string_loc->string_override
  707. : $obj_string_loc->string_default;
  708. }
  709. // If we didn't hit, load the English default
  710. if(empty($string))
  711. @$string =
  712. (!empty($obj_string_en->string_override))
  713. ? $obj_string_en->string_override
  714. : $obj_string_en->string_default;
  715. // If we found any match
  716. if(!empty($string))
  717. $map[$string_id] = $string;
  718. }
  719. unset($obj_string_en);
  720. unset($obj_string_loc);
  721. unset($map_en);
  722. unset($map_loc);
  723. // Cache with tag (tag allows easy clean for multiple langs at once)
  724. $cache->save($map,self::CACHE_TAG_TRANSLATIONS.'_'.$locale,array(self::CACHE_TAG_TRANSLATIONS));
  725. }
  726. $translate = _DevblocksTranslationManager::getInstance();
  727. $translate->addLocale($locale, $map);
  728. $translate->setLocale($locale);
  729. Zend_Registry::set('Devblocks:getTranslationService:'.$locale, $translate);
  730. return $translate;
  731. }
  732. /**
  733. * Enter description here...
  734. *
  735. * @return DevblocksHttpRequest
  736. */
  737. static function getHttpRequest() {
  738. return self::$request;
  739. }
  740. /**
  741. * @param DevblocksHttpRequest $request
  742. */
  743. static function setHttpRequest(DevblocksHttpRequest $request) {
  744. self::$request = $request;
  745. }
  746. /**
  747. * Enter description here...
  748. *
  749. * @return DevblocksHttpRequest
  750. */
  751. static function getHttpResponse() {
  752. return self::$response;
  753. }
  754. /**
  755. * @param DevblocksHttpResponse $response
  756. */
  757. static function setHttpResponse(DevblocksHttpResponse $response) {
  758. self::$response = $response;
  759. }
  760. /**
  761. * Initializes the plugin platform (paths, etc).
  762. *
  763. * @static
  764. * @return void
  765. */
  766. static function init() {
  767. self::$start_time = microtime(true);
  768. if(function_exists('memory_get_usage') && function_exists('memory_get_peak_usage')) {
  769. self::$start_memory = memory_get_usage();
  770. self::$start_peak_memory = memory_get_peak_usage();
  771. }
  772. // Encoding (mbstring)
  773. mb_internal_encoding(LANG_CHARSET_CODE);
  774. // [JAS] [MDF]: Automatically determine the relative webpath to Devblocks files
  775. @$proxyhost = $_SERVER['HTTP_DEVBLOCKSPROXYHOST'];
  776. @$proxybase = $_SERVER['HTTP_DEVBLOCKSPROXYBASE'];
  777. // App path (always backend)
  778. $app_self = $_SERVER["PHP_SELF"];
  779. if(DEVBLOCKS_REWRITE) {
  780. $pos = strrpos($app_self,'/');
  781. $app_self = substr($app_self,0,$pos) . '/';
  782. } else {
  783. $pos = strrpos($app_self,'index.php');
  784. if(false === $pos) $pos = strrpos($app_self,'ajax.php');
  785. $app_self = substr($app_self,0,$pos);
  786. }
  787. // Context path (abstracted: proxies or backend)
  788. if(!empty($proxybase)) { // proxy
  789. $context_self = $proxybase . '/';
  790. } else { // non-proxy
  791. $context_self = $app_self;
  792. }
  793. @define('DEVBLOCKS_WEBPATH',$context_self);
  794. @define('DEVBLOCKS_APP_WEBPATH',$app_self);
  795. }
  796. // static function setPluginDelegate($class) {
  797. // if(!empty($class) && class_exists($class, true))
  798. // self::$pluginDelegate = $class;
  799. // }
  800. static function setExtensionDelegate($class) {
  801. if(!empty($class) && class_exists($class, true))
  802. self::$extensionDelegate = $class;
  803. }
  804. static function redirect(DevblocksHttpIO $httpIO) {
  805. $url_service = self::getUrlService();
  806. session_write_close();
  807. $url = $url_service->writeDevblocksHttpIO($httpIO, true);
  808. header('Location: '.$url);
  809. exit;
  810. }
  811. };
  812. // [TODO] This doesn't belong! (ENGINE)
  813. class PlatformPatchContainer extends DevblocksPatchContainerExtension {
  814. function __construct() {
  815. parent::__construct(null);
  816. /*
  817. * [JAS]: Just add a build number here (from your commit revision) and write a
  818. * case in runBuild(). You should comment the milestone next to your build
  819. * number.
  820. */
  821. $file_prefix = dirname(__FILE__) . '/patches/';
  822. $this->registerPatch(new DevblocksPatch('devblocks.core',1,$file_prefix.'1.0.0.php',''));
  823. $this->registerPatch(new DevblocksPatch('devblocks.core',253,$file_prefix.'1.0.0_beta.php',''));
  824. $this->registerPatch(new DevblocksPatch('devblocks.core',290,$file_prefix.'1.1.0.php',''));
  825. $this->registerPatch(new DevblocksPatch('devblocks.core',297,$file_prefix.'2.0.0.php',''));
  826. }
  827. };