PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/application/libraries/doc/fx_config.php

http://comet.googlecode.com/
PHP | 506 lines | 308 code | 58 blank | 140 comment | 75 complexity | 82082516094cb510fb39eac0aee13447 MD5 | raw file
Possible License(s): AGPL-3.0
  1. <?php
  2. class Fx_Config {
  3. const XML_NAMESPACE = 'http://flashstar_ex.com/project/framework/ci';
  4. protected $_instance = NULL;
  5. protected $_baseDir = 'config/';
  6. protected $_module = '';
  7. protected $_file = 'config.xml';
  8. protected $_isLoaded = FALSE;
  9. protected $_allowModified = TRUE;
  10. protected $_data = array();
  11. protected $_loadedSections = array();
  12. protected $_loadedXmlFiles = array();
  13. protected $_doc = NULL;
  14. public function __construct($_file = 'config.xml', $_module = NULL, $_baseDir = 'config/', $_isReadOnly = FALSE) {
  15. $this->loadConfig($_file, $_module, $_baseDir);
  16. }
  17. /**
  18. * SINGLETON PATTERN
  19. * @return: Fx_Config
  20. */
  21. public function getInstance() {
  22. if (NULL === self::$_instance) {
  23. self::$_instance = new self();
  24. }
  25. return self::$_instance;
  26. }
  27. /**
  28. * GET CONFIG DATA
  29. * @return: Fx_Config
  30. */
  31. public function getConfigData() {
  32. return (array)$this->_data;
  33. }
  34. /**
  35. * GET CONFIG DATA
  36. * @return: Fx_Config
  37. */
  38. public function setConfigData($_data) {
  39. // If Data Is SimpleXMLElement
  40. if ($_data instanceof SimpleXMLElement) {
  41. $this->_data = array();
  42. $this->_recursiveData($_data);
  43. // If Data Is Array
  44. } else if (is_array($_data)) {
  45. $this->_data = $_data;
  46. // If Data Is String XML Data
  47. } else if (is_string($_data)) {
  48. $doc = simplexml_load_string($_data, 'SimpleXMLElement');
  49. if ($doc instanceof SimpleXMLElement) {
  50. $this->_recursiveData($doc);
  51. }
  52. }
  53. return $this;
  54. }
  55. /**
  56. * RESET ALL DATA OF CONFIG CLASS
  57. * @return: Fx_Config
  58. */
  59. public function resetData() {
  60. $this->_baseDir = 'config/';
  61. $this->_module = '';
  62. $this->_file = 'config.xml';
  63. $this->_isLoaded = FALSE;
  64. $this->_allowModified = TRUE;
  65. $this->_data = array();
  66. $this->_loadedSections = array();
  67. $this->_loadedXmlFiles = array();
  68. $this->_doc = NULL;
  69. return $this;
  70. }
  71. /**
  72. * RELOAD DATA OF CONFIG CLASS
  73. * @return: Fx_Config
  74. */
  75. public function reload() {
  76. $this->resetData();
  77. $this->loadConfig($this->_getFileConfig(), $this->_getModule(), FALSE);
  78. return $this;
  79. }
  80. /**
  81. * LOAD CONFIG MAUNAL OR AUTO
  82. * @param: String (filename)
  83. * @param: String (module name, if not set then get current module)
  84. * @param: Boolean (Use Namespace)
  85. * @return: Fx_Config
  86. */
  87. public function loadConfig($file = '', $_module = NULL, $baseDir = 'config/', $useNS = FALSE) {
  88. // Set Default File Config
  89. ($file == '') AND $file = 'config.xml';
  90. $_module || $_module = CI::$APP->router->fetch_module();
  91. // If Fetch Module Successful, Then Set Current Module Of Config
  92. if ($_module) {
  93. $this->_setModule($_module);
  94. }
  95. // Get Full Path Of Config File
  96. if (empty($baseDir)) {
  97. $baseDir = $this->_getBaseDir();
  98. }
  99. $file = implode('', Modules::find($file, $_module, $baseDir));
  100. if (!file_exists($file)) {
  101. throw new Exception('XML Config File Not Exists');
  102. }
  103. // Check Using NameSpace XML
  104. if (!$useNS) {
  105. $config_document = simplexml_load_file($file, 'SimpleXMLElement', LIBXML_NOBLANKS | LIBXML_COMPACT);
  106. } else {
  107. $config_document = simplexml_load_file($file, 'SimpleXMLElement', LIBXML_NOBLANKS | LIBXML_COMPACT, self::XML_NAMESPACE, FALSE);
  108. }
  109. // Check Loaded XML Document Succsessfully
  110. if (!$config_document instanceof SimpleXMLElement) {
  111. throw new Exception('IMPORT XML FILE FAILURE');
  112. }
  113. // Check Empty Config
  114. if (count($config_document->children()) == 0) {
  115. return $this;
  116. }
  117. //print_r (get_class_methods($config_document));
  118. //Traverse On XML Document
  119. $this->_recursiveData($config_document);
  120. // Set File Config
  121. $this->_setFileConfig($file);
  122. // Set Loaded
  123. $this->_isLoaded = TRUE;
  124. // Add XML Loaded Files
  125. $this->_loadedXmlFiles[$file] = $config_document;
  126. // Set Current Document
  127. $this->setDocument($config_document);
  128. //print_r($this->_data);
  129. return $this;
  130. }
  131. /**
  132. * TRAVERSING DATA OF AN ELEMENT THEN ADD KEY AND VALUE OF IT
  133. * TO SECTIONS OF CONFIG
  134. * @param: SimpleXMLElement
  135. * @return: Fx_Config
  136. */
  137. public function _recursiveData(SimpleXMLElement $element) {
  138. if (!$element->children()) {
  139. $this->_data[$element->getName()] = $element;
  140. } else {
  141. $children = $element->children();
  142. foreach ($children as $key => $child) {
  143. $this->_data[$element->getName()][$key] = $child;
  144. if (count($child->children()) > 0) {
  145. $this->_recursiveData($child);
  146. }
  147. }
  148. }
  149. return $this;
  150. }
  151. /**
  152. * LOAD CONFIG MAUNAL OR AUTO
  153. * @param: String (Section Key: Key In _loadedSections Array)
  154. * @param: String (xml string)
  155. * @return: Fx_Config
  156. */
  157. public function loadSection($sectionKey = '', $data = '') {
  158. if (!is_string($data) || empty($data)) {
  159. return $this;
  160. }
  161. $config_document = simplexml_load_string($file, 'SimpleXMLElement', LIBXML_ERR_WARNING | LIBXML_XINCLUDE | LIBXML_NOBLANKS);
  162. // Check Loaded XML Document Succsessfully
  163. if (!$config_document instanceof SimpleXMLElement) {
  164. throw new Exception('IMPORT XML STRING FAILURE');
  165. }
  166. if (!$sectionKey) {
  167. $sectionKey = md5(time());
  168. }
  169. //Traverse On XML Document
  170. $this->_recursiveSection($sectionKey, $config_document);
  171. // Set Current Document
  172. $this->setDocument($config_document);
  173. return $this;
  174. }
  175. /**
  176. * TRAVERSING DATA OF AN ELEMENT THEN ADD KEY AND VALUE OF IT
  177. * TO DATA OF CONFIG
  178. * @param: SimpleXMLElement
  179. * @return: Fx_Config
  180. */
  181. public function _recursiveSection($sectionKey, SimpleXMLElement $element) {
  182. if (!$element->children()) {
  183. $this->_loadedSections[$sectionKey][$element->getName()] = $element;
  184. } else {
  185. $children = $element->children();
  186. foreach ($children as $key => $child) {
  187. $this->_loadedSections[$sectionKey][$element->getName()][$key] = $child;
  188. if (count($child->children()) > 0) {
  189. $this->_recursiveSection($child);
  190. }
  191. }
  192. }
  193. return $this;
  194. }
  195. /**
  196. * GET NODE CONTENT
  197. * @return: String
  198. */
  199. public function getNodeContent($xQuery = '', $index = 0, $doc = null) {
  200. if (!is_string($xQuery) || empty($xQuery)) {
  201. return null;
  202. }
  203. if (empty($doc)) {
  204. $doc =& $this->getDocument();
  205. if ($doc === NULL) {
  206. return NULL;
  207. }
  208. }
  209. // Search Node
  210. $node = $doc->xpath($xQuery);
  211. // Return Value
  212. return (isset($node[$index][0])) ? $node[$index][0] : NULL;
  213. }
  214. /**
  215. * UPDATE NODE DATA
  216. * @param: String (xquery)
  217. * @param: String (new value)
  218. * @param: SimpleXMLElement (doc)
  219. * @param: String (Destionation File To Save)
  220. * @param: Integer (Index Of Node, Default Is 0)
  221. * @param: Boolean (Index Of Node, Default Is 0)
  222. * @return: Fx_Config
  223. */
  224. public function updateNodeContent($xQuery = '', $value = '', $index = 0, $doc = NULL) {
  225. // If Config Data In ReadOnly Then Exit
  226. if ($this->_isReadOnly()) {
  227. return $this;
  228. }
  229. if (!is_string($xQuery) || empty($xQuery) || !is_string($value) || empty($value) ) {
  230. return $this;
  231. }
  232. if (empty($doc) || $doc instanceof SimpleXMLElement) {
  233. $doc =& $this->getDocument();
  234. if ($doc === NULL) {
  235. return $this;
  236. }
  237. }
  238. if (empty($filePath)) {
  239. $filePath = $this->_getFileConfig();
  240. }
  241. // Search Node
  242. $node = $doc->xpath($xQuery);
  243. // Change Value
  244. $node[$index][0] = $value;
  245. /*
  246. $dom = dom_import_simplexml($doc)->ownerDocument;
  247. $dom->formatOutput = true;
  248. file_put_contents($filePath, $dom->saveXML());
  249. // If Refresh Data
  250. if ($refresh) {
  251. $this->loadConfig(substr($filePath, strrpos($filePath, "/")));
  252. }
  253. */
  254. return $this;
  255. }
  256. /**
  257. * GET NODE
  258. *
  259. */
  260. public function getNode($xQuery = '', $index = 0, $doc = null) {
  261. if (!is_string($xQuery) || empty($xQuery)) {
  262. return $this;
  263. }
  264. if (empty($doc)) {
  265. $doc =& $this->getDocument();
  266. if ($doc === NULL) {
  267. return $this;
  268. }
  269. }
  270. // Search Node
  271. $node = $doc->xpath($xQuery);
  272. // Change Value
  273. if (isset($node[$index])) {
  274. return $node[$index];
  275. }
  276. return NULL;
  277. }
  278. /**
  279. * ADD NODE
  280. *
  281. */
  282. public function addNode($node = NULL, $doc = NULL, $index = 0) {
  283. if (empty($node )) {
  284. return $this;
  285. }
  286. if (empty($doc)) {
  287. $doc =& $this->getDocument();
  288. if ($doc === NULL) {
  289. return $this;
  290. }
  291. }
  292. if (!$node instanceof SimpleXMLElement) {
  293. $node = simplexml_import_dom($node);
  294. }
  295. $doc->addChild($node->getName(), $node);
  296. return $this;
  297. }
  298. /**
  299. * SAVE XML
  300. *
  301. */
  302. public function saveXML($filePath = '', $doc = NULL, $refresh = TRUE) {
  303. if (empty($filePath)) {
  304. $filePath = $this->_getFileConfig();
  305. if (empty($filePath)) {
  306. return $this;
  307. }
  308. }
  309. if (empty($doc)) {
  310. $doc =& $this->getDocument();
  311. if ($doc === NULL) {
  312. return $this;
  313. }
  314. }
  315. $dom = dom_import_simplexml($doc)->ownerDocument;
  316. $dom->formatOutput = true;
  317. file_put_contents($filePath, $dom->saveXML());
  318. // If Refresh Data
  319. if ($refresh) {
  320. $this->loadConfig(substr($filePath, strrpos($filePath, "/")));
  321. }
  322. return $this;
  323. }
  324. public function getDocument() {
  325. return $this->_doc;
  326. }
  327. public function setDocument(SimpleXMLElement $document) {
  328. $this->_doc = $document;
  329. return $this;
  330. }
  331. public function _setFileConfig($_file) {
  332. if (!is_string($_file)) {
  333. return $this;
  334. }
  335. $this->_file = $_file;
  336. return $this;
  337. }
  338. public function _getFileConfig() {
  339. return (string)$this->_file;
  340. }
  341. public function _setBaseDir($base) {
  342. if (!is_string($base)) {
  343. return $this;
  344. }
  345. $this->_baseDir = base;
  346. return $this;
  347. }
  348. public function _getBaseDir() {
  349. return (string)$this->_baseDir;
  350. }
  351. public function _isLoaded() {
  352. return (boolean)$this->isLoaded;
  353. }
  354. public function _getModule() {
  355. return (string)$this->_module;
  356. }
  357. public function _setModule($_module) {
  358. if (!is_string($_module)) {
  359. return $this;
  360. }
  361. $this->_module = $_module;
  362. return $this;
  363. }
  364. public function setReadOnly($flag = FALSE) {
  365. $this->_allowModified = $flag;
  366. return $this;
  367. }
  368. public function _isReadOnly() {
  369. return !(boolean)$this->_allowModified;
  370. }
  371. }
  372. class ArrayToXML
  373. {
  374. /**
  375. * The main function for converting to an XML document.
  376. * Pass in a multi dimensional array and this recrusively loops through and builds up an XML document.
  377. *
  378. * @param array $data
  379. * @param string $rootNodeName - what you want the root node to be - defaultsto data.
  380. * @param SimpleXMLElement $xml - should only be used recursively
  381. * @return string XML
  382. */
  383. public static function toXML( $data, $rootNodeName = 'ResultSet', &$xml=null ) {
  384. // turn off compatibility mode as simple xml throws a wobbly if you don't.
  385. if ( ini_get('zend.ze1_compatibility_mode') == 1 ) ini_set ( 'zend.ze1_compatibility_mode', 0 );
  386. if ( is_null( $xml ) ) $xml = simplexml_load_string( "" );
  387. // loop through the data passed in.
  388. foreach( $data as $key => $value ) {
  389. // no numeric keys in our xml please!
  390. if ( is_numeric( $key ) ) {
  391. $numeric = 1;
  392. $key = $rootNodeName;
  393. }
  394. // delete any char not allowed in XML element names
  395. $key = preg_replace('/[^a-z0-9\-\_\.\:]/i', '', $key);
  396. // if there is another array found recrusively call this function
  397. if ( is_array( $value ) ) {
  398. $node = ArrayToXML::is_assoc( $value ) || $numeric ? $xml->addChild( $key ) : $xml;
  399. // recrusive call.
  400. if ( $numeric ) $key = 'anon';
  401. ArrayToXML::toXml( $value, $key, $node );
  402. } else {
  403. // add single node.
  404. $value = htmlentities( $value );
  405. $xml->addChild( $key, $value );
  406. }
  407. }
  408. // pass back as XML
  409. return $xml->asXML();
  410. // if you want the XML to be formatted, use the below instead to return the XML
  411. //$doc = new DOMDocument('1.0');
  412. //$doc->preserveWhiteSpace = false;
  413. //$doc->loadXML( $xml->asXML() );
  414. //$doc->formatOutput = true;
  415. //return $doc->saveXML();
  416. }
  417. /**
  418. * Convert an XML document to a multi dimensional array
  419. * Pass in an XML document (or SimpleXMLElement object) and this recrusively loops through and builds a representative array
  420. *
  421. * @param string $xml - XML document - can optionally be a SimpleXMLElement object
  422. * @return array ARRAY
  423. */
  424. public static function toArray( $xml ) {
  425. if ( is_string( $xml ) ) $xml = new SimpleXMLElement( $xml );
  426. $children = $xml->children();
  427. if ( !$children ) return (string) $xml;
  428. $arr = array();
  429. foreach ( $children as $key => $node ) {
  430. $node = ArrayToXML::toArray( $node );
  431. // support for 'anon' non-associative arrays
  432. if ( $key == 'anon' ) $key = count( $arr );
  433. // if the node is already set, put it into an array
  434. if ( isset( $arr[$key] ) ) {
  435. if ( !is_array( $arr[$key] ) || $arr[$key][0] == null ) $arr[$key] = array( $arr[$key] );
  436. $arr[$key][] = $node;
  437. } else {
  438. $arr[$key] = $node;
  439. }
  440. }
  441. return $arr;
  442. }
  443. // determine if a variable is an associative array
  444. public static function isAssoc( $array ) {
  445. return (is_array($array) && 0 !== count(array_diff_key($array, array_keys(array_keys($array)))));
  446. }
  447. }
  448. ?>