Source for file application-defs.php

Documentation is available at application-defs.php

  1. <?php
  2. /* ******************************************************************** */
  3. /* CATALYST PHP Source Code */
  4. /* -------------------------------------------------------------------- */
  5. /* This program is free software; you can redistribute it and/or modify */
  6. /* it under the terms of the GNU General Public License as published by */
  7. /* the Free Software Foundation; either version 2 of the License, or */
  8. /* (at your option) any later version. */
  9. /* */
  10. /* This program is distributed in the hope that it will be useful, */
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  13. /* GNU General Public License for more details. */
  14. /* */
  15. /* You should have received a copy of the GNU General Public License */
  16. /* along with this program; if not, write to: */
  17. /* The Free Software Foundation, Inc., 59 Temple Place, Suite 330, */
  18. /* Boston, MA 02111-1307 USA */
  19. /* -------------------------------------------------------------------- */
  20. /* */
  21. /* Filename: application-defs.php */
  22. /* Author: Paul Waite */
  23. /* Description: Basic definitions pertaining to application config. */
  24. /* */
  25. /* ******************************************************************** */
  26. /** @package core */
  27. include_once("xml-defs.php");
  28. /** Filesystem access */
  29. ("file-defs.php");
  30. // ----------------------------------------------------------------------
  31. /**
  32. * A parameter class to contain setting parameter information. Every
  33. * parameter has an idetifying name, and a type. The value of a
  34. * parameter can be an array of name=>value pairs, or a scalar type
  35. * such as a string, integer or boolean.
  36. * @package core
  37. */
  38. class parameter {
  39. /** Parameter name */
  40.  
  41. var $name = "";
  42. /** Parameter type */
  43.  
  44. var $type = "";
  45. /** Parameter value */
  46.  
  47. var $value = "";
  48. // .....................................................................
  49. /**
  50. * Make a new parameter.
  51. * @param string $name Name of this parameter
  52. * @param string $type Parameter type eg: 'array', 'string' etc.
  53. */
  54. function parameter($name, $type) {
  55. $this->name = $name;
  56. $this->type = $type;
  57. if ($type == "array") {
  58. $this->value = array();
  59. }
  60. }
  61. // .....................................................................
  62. /**
  63. * Set the parameter to given value. If the parameter has an
  64. * array of values, the name is also given.
  65. * @param mixed $value Value to assign to this parameter
  66. * @param string $ename Name of this value (arrayed parameters only)
  67. */
  68. function setvalue($value, $ename="") {
  69. if ($this->type == "array") {
  70. $this->value[$ename] = $value;
  71. }
  72. elseif ($this->type == "boolean"||$this->type == "bool") {
  73. $this->value = (($value === "true"||$value === "t"||$value === true) ? true : false);
  74. }
  75. else {
  76. $this->value = $value;
  77. }
  78. }
  79. // .....................................................................
  80. /**
  81. * Get the parameter value. If the element name is given (for an
  82. * array type parameter) then we return the value of that element.
  83. * @param string $ename Name of this value (arrayed parameters only)
  84. */
  85. function getvalue($ename="") {
  86. if ($this->type == "array") {
  87. return $this->value[$ename];
  88. }
  89. else {
  90. return $this->value;
  91. }
  92. }
  93. // .....................................................................
  94. /**
  95. * Return decoded value (or array of values) so that applications can use
  96. * the data unencumbered with URL encoding etc.
  97. * @return mixed Value or array of values which have been urldecoded
  98. */
  99. function get_decodedvalue() {
  100. switch ($this->type) {
  101. case "array":
  102. $rar = array();
  103. foreach ($this->value as $name => $value) {
  104. $rar[$name] = rawurldecode($value);
  105. }
  106. return $rar;
  107. break;
  108.  
  109. case "boolean":
  110. return $this->value;
  111. break;
  112.  
  113. default:
  114. return rawurldecode($this->value);
  115. }
  116. }
  117. // .....................................................................
  118. /** Dump this parameter */
  119.  
  120. function htmldump() {
  121. $s = "";
  122. $s .= "parameter: $this->name ($this->type) ";
  123. if ($this->type == "array") {
  124. $s .= "values:";
  125. foreach ($this->value as $ename => $val) {
  126. $s .= " [$ename = '$val']";
  127. }
  128. }
  129. else {
  130. $s .= "value = '$this->value'";
  131. }
  132. return $s . "<br>";
  133. }
  134. } // parameter class
  135. // .......................................................................
  136.  
  137. /**
  138. * Application settings class. This class contains one or more parameters.
  139. * A setting can also have an 'agent' defined which will action it. This
  140. * can, for example, be the name of a function, if used.
  141. * @package core
  142. */
  143. class setting {
  144. /** Name of this setting */
  145.  
  146. var $name = "";
  147. /** Agent which will action this setting */
  148.  
  149. var $agent = "";
  150. /* Array of parameters for this setting */
  151. var $parameters = array();
  152. // .....................................................................
  153. /** Make a new setting */
  154.  
  155. function setting($name="", $agent="") {
  156. $this->name = $name;
  157. $this->agent = $agent;
  158. }
  159. // .....................................................................
  160. /**
  161. * Add the given parameter to this setting.
  162. * @param string $pname Name of the parameter to add
  163. * @param object $parm Parameter object to add to this setting
  164. */
  165. function addparameter($pname, $parm) {
  166. $this->parameters[$pname] = $parm;
  167. }
  168. // .....................................................................
  169. /**
  170. * Add a new parameter to this setting, with given value and type. For
  171. * arrays we also specify the name of the array value.
  172. * @param string $pname Name of the new parameter to add
  173. * @param mixed $value Value to assign to this parameter
  174. * @param string $type Parameter type eg: 'array', 'string' etc.
  175. * @param string $ename Name of this value (arrayed parameters only)
  176. */
  177. function newparameter($pname, $value, $type, $ename="") {
  178. $parm = new parameter($pname, $type);
  179. $parm->setvalue($value, $ename);
  180. $this->addparameter($pname, $parm);
  181. }
  182. // .....................................................................
  183. /**
  184. * Set the value of a parameter which already exists in this
  185. * setting.
  186. * @param string $pname Name of the parameter to set value of
  187. * @param mixed $value Value to set in the parameter
  188. * @param string $ename Name of this value (arrayed parameters only)
  189. */
  190. function setparameter($pname, $value, $ename="") {
  191. if (isset($this->parameters[$pname])) {
  192. $this->parameters[$pname]->setvalue($value, $ename);
  193. }
  194. }
  195. // .....................................................................
  196. /**
  197. * Get the value of a named parameter.
  198. * @param string $pname Name of the parameter to get value of
  199. * @param string $ename Name of element (arrayed parameters only)
  200. */
  201. function getparameter($pname, $ename="") {
  202. $val = false;
  203. if (isset($this->parameters) && isset($this->parameters[$pname])) {
  204. $parm = $this->parameters[$pname];
  205. $val = $parm->getvalue($ename);
  206. }
  207. return $val;
  208. }
  209. // .....................................................................
  210. /** Dump setting */
  211.  
  212. function htmldump() {
  213. $s = "";
  214. $s .= "Setting: agent = '$this->agent'<br>";
  215. foreach ($this->parameters as $parm) {
  216. $s .= $parm->htmldump();
  217. }
  218. return $s;
  219. }
  220. } // setting class
  221. // ----------------------------------------------------------------------
  222.  
  223. /**
  224. * Class comprising the functionality of an application. This is used
  225. * to contain and manage the basic configuration properties of an
  226. * application. This class knows how to read the configuration in,
  227. * store the values, and write it out again.
  228. * @package core
  229. */
  230. class application extends xmlparser {
  231. /** Path to application configuration file */
  232.  
  233. var $configpath = "";
  234. /** State of processing */
  235.  
  236. var $state = "";
  237. /** Current/last tag opened */
  238.  
  239. var $tag = "";
  240. /** Attributes array for current/last tag */
  241.  
  242. var $attr = array();
  243. /** True if response was valid, ie. no errors */
  244.  
  245. var $valid = false;
  246. // .....................................................................
  247. // Application configuration..
  248. var $definitions = array();
  249. var $globals = array();
  250. var $settings = array();
  251. // .....................................................................
  252. /**
  253. * Construct a new application. Creating the application will also attempt
  254. * to read in the XML configuration file as specified (or defaulted). If
  255. * the file is read successfully, then the valid flag is set true.
  256. * @param string $configpath Path to XML configuration file for application
  257. */
  258. function application($configpath="application.xml") {
  259. $this->configpath = $configpath;
  260. $this->xmlparser();
  261. if (file_exists($this->configpath)) {
  262. $xmlfile = new inputfile($this->configpath);
  263. if ($xmlfile->opened) {
  264. $xmlfile->readall();
  265. $xmlfile->closefile();
  266. $this->parse($xmlfile->content);
  267. $this->valid = $this->valid_xml;
  268. }
  269. }
  270. }
  271. // .....................................................................
  272. /**
  273. * Make this current application object the same structure as the
  274. * given application. This process checks that the definitions, globals,
  275. * and settings of this application match those of the given one. If
  276. * a given item is missing, it is created. If an item is not present
  277. * in the given application, it is deleted in this one. Existing items
  278. * retain their current values - only structure is checked.
  279. * @param object $refapp The reference application to synchronize to
  280. * @return boolean True if changes were made, else false.
  281. */
  282. function synchronize($refapp) {
  283. if ($refapp->valid) {
  284. $synced = false;
  285. // Definitions..
  286. foreach ($refapp->definitions as $name => $val) {
  287. if (!isset($this->definitions[$name])) {
  288. $this->definitions[$name] = $val;
  289. $synced = true;
  290. }
  291. }
  292. foreach ($this->definitions as $name => $val) {
  293. if (!isset($refapp->definitions[$name])) {
  294. unset($this->definitions[$name]);
  295. $synced = true;
  296. }
  297. }
  298.  
  299. // Globals..
  300. foreach ($refapp->globals as $name => $val) {
  301. if (!isset($this->globals[$name])) {
  302. $this->globals[$name] = $val;
  303. $synced = true;
  304. }
  305. }
  306. foreach ($this->globals as $name => $val) {
  307. if (!isset($refapp->globals[$name])) {
  308. unset($this->globals[$name]);
  309. $synced = true;
  310. }
  311. }
  312.  
  313. // Settings..
  314. foreach ($refapp->settings as $ref_setting) {
  315. if ($ref_setting->name != "database") {
  316. if ($this->get_setting($ref_setting->name) === false) {
  317. $this->settings[] = $ref_setting;
  318. error_log("adding new setting $ref_setting->name");
  319. $synced = true;
  320. }
  321. }
  322. }
  323. $newsettings = array();
  324. for ($ix = 0; $ix < count($this->settings); $ix++) {
  325. $setting = $this->settings[$ix];
  326. if ($setting->name == "database") {
  327. $newsettings[] = $setting;
  328. }
  329. else {
  330. if ($setting->name != "") {
  331. if ($refapp->get_setting($setting->name) !== false) {
  332. $newsettings[] = $setting;
  333. }
  334. else {
  335. error_log("removing setting $setting->name");
  336. $synced = true;
  337. }
  338. }
  339. }
  340. }
  341. $this->settings = $newsettings;
  342. }
  343. return $synced;
  344. }
  345. // .....................................................................
  346. /**
  347. * Return setting by name. NB: some settings can have multiple entries
  348. * under the same name, eg. 'database'. In this case we return an
  349. * array of setting objects, otherwise the single setting object.
  350. * We return false if not found.
  351. * @param string $name Name of the setting(s) to return
  352. * @return mixed Single setting object, array of settings, or false
  353. */
  354. function get_setting($name) {
  355. $got = array();
  356. foreach ($this->settings as $setting) {
  357. if ($setting->name == $name) {
  358. $got[] = $setting;
  359. }
  360. }
  361. if (count($got) == 0) {
  362. return false;
  363. }
  364. elseif (count($got) == 1) {
  365. return $got[0];
  366. }
  367. else {
  368. return $got;
  369. }
  370. }
  371. // .....................................................................
  372. /**
  373. * Get the value of a named parameter from a named setting. This only
  374. * works for settings which are unique - ie. it won't work well for
  375. * parms which can occur multiple times, eg: 'database'. Option to
  376. * specify the element name for arrayed parameters.
  377. * @param string $name Name of the setting which contains the parameter
  378. * @param string $pname Name of the parameter to get value of
  379. * @param string $ename Name of element (arrayed parameters only)
  380. */
  381. function getparameter($name, $pname, $ename="") {
  382. $parm = "";
  383. if (isset($this->settings)) {
  384. if ($setting = $this->get_setting($name)) {
  385. $parm = $setting->getparameter($pname, $ename);
  386. }
  387. }
  388. return $parm;
  389. }
  390. // .....................................................................
  391. /**
  392. * Set the value of a named parameter for a named setting. Optionally
  393. * provide the element name for arrayed parameters.
  394. * @param mixed $value Value of the parameter setting
  395. * @param string $name Name of the setting which contains the parameter
  396. * @param string $pname Name of the parameter to get value of
  397. * @param string $ename Name of element (arrayed parameters only)
  398. */
  399. function setparameter($value, $name, $pname, $ename="") {
  400. $parm = "";
  401. if (isset($this->settings)) {
  402. $pix = -1;
  403. for ($ix = 0; $ix < count($this->settings); $ix++) {
  404. if ($this->settings[$ix]->name == $name) {
  405. $pix = $ix;
  406. break;
  407. }
  408. }
  409. if ($pix > -1) {
  410. $this->settings[$pix]->setparameter($pname, $value, $ename);
  411. }
  412. }
  413. return $parm;
  414. }
  415. // .....................................................................
  416. /**
  417. * Return dump of the application content as a string. Useful for
  418. * diagnostics mainly.
  419. * @return string Dump of the application content as html string.
  420. */
  421. function htmldump() {
  422. $s = "APPLICATION<br>";
  423. $s .= "Definitions:<br>";
  424. foreach ($this->definitions as $name => $val) {
  425. $s .= "$name = '$val'<br>";
  426. }
  427. $s .= "Globals:<br>";
  428. foreach ($this->globals as $name => $val) {
  429. $s .= "$name = '$val'<br>";
  430. }
  431. $s .= "Settings:<br>";
  432. foreach ($this->settings as $setting) {
  433. $s .= $setting->htmldump();
  434. }
  435. return $s;
  436. }
  437. // .....................................................................
  438. /**
  439. * Save the application as XML file back to the same filename it was
  440. * read in from, ie. after changes have been made. This generates
  441. * the whole file as fresh XML, and writes it out.
  442. */
  443. function save() {
  444. if ($this->valid && is_writeable($this->configpath)) {
  445. $xmlfile = new outputfile($this->configpath);
  446. if ($xmlfile->opened) {
  447. $xml = new xmltag("application");
  448.  
  449. // DEFINITIONS
  450. $xmldefs = new xmltag("definitions");
  451. foreach ($this->definitions as $name => $val) {
  452. $xmldef = new xmltag("definition", $val);
  453. $xmldef->setattribute("name", $name);
  454. $xmldefs->childtag($xmldef);
  455. }
  456. $xml->childtag($xmldefs);
  457.  
  458. // GLOBALS
  459. $xmlglobs = new xmltag("globals");
  460. foreach ($this->globals as $name => $val) {
  461. $xmlglob = new xmltag("global", $val);
  462. $xmlglob->setattribute("name", $name);
  463. $xmlglobs->childtag($xmlglob);
  464. }
  465. $xml->childtag($xmlglobs);
  466.  
  467. // RESPONSE SETTINGS
  468. $xmlsettings = new xmltag("settings");
  469. foreach ($this->settings as $setting) {
  470. $xmlsetting = new xmltag("setting");
  471. $xmlsetting->setattribute("name", $setting->name);
  472. $xmlsetting->setattribute("agent", $setting->agent);
  473. foreach ($setting->parameters as $parameter) {
  474. $xmlparm = new xmltag("parameter");
  475. $xmlparm->setattribute("name", $parameter->name);
  476. $xmlparm->setattribute("type", $parameter->type);
  477. if ($parameter->type == "array") {
  478. if (is_array($parameter->value) && count($parameter->value) > 0) {
  479. foreach ($parameter->value as $ename => $evalue) {
  480. $xmlelem = new xmltag("element", $evalue);
  481. $xmlelem->setattribute("name", $ename);
  482. $xmlparm->childtag($xmlelem);
  483. }
  484. }
  485. }
  486. else {
  487. $xmlparm->value = $parameter->value;
  488. }
  489. $xmlsetting->childtag($xmlparm);
  490. }
  491. $xmlsettings->childtag($xmlsetting);
  492. }
  493. $xml->childtag($xmlsettings);
  494.  
  495. // Write the file content..
  496. $xmlfile->writeln( xmlheader() );
  497. $xmlfile->writeln("<!-- Axyl XML Configuration File - Please do not edit this file directly. -->");
  498. $xmlfile->writeln("<!-- The settings in this file determine how your application will run. -->");
  499. $xmlfile->writeln("<!-- Generation timestamp: " . timestamp_to_displaydate(NICE_FULLDATETIME, time()) . " -->");
  500. $xmlfile->write( $xml->render() );
  501. $xmlfile->closefile();
  502. } // if file opened
  503. } // if valid
  504. }
  505. // .....................................................................
  506. /** Method invoked when a tag is opened */
  507.  
  508. function tag_open($parser, $tag, $attributes) {
  509. $this->tag = $tag;
  510. if (is_array($attributes) && count($attributes) > 0) {
  511. foreach ($attributes as $key => $value ) {
  512. $this->attr[$key] = $value;
  513. }
  514. }
  515. switch ($this->tag) {
  516. case "definition":
  517. $this->definitions[ $this->attr["name"] ] = "";
  518. break;
  519. case "global":
  520. $this->globals[ $this->attr["name"] ] = "";
  521. break;
  522. case "setting":
  523. $this->setting = new setting( $this->attr["name"], $this->attr["agent"] );
  524. break;
  525. case "parameter":
  526. $this->parameter = new parameter( $this->attr["name"], $this->attr["type"] );
  527. break;
  528. } // switch
  529. }
  530. // .....................................................................
  531. /** Method invoked when character data is available */
  532.  
  533. function cdata($parser, $cdata) {
  534. switch ($this->tag) {
  535. case "definition":
  536. $this->definitions[ $this->attr["name"] ] = $cdata;
  537. break;
  538. case "global":
  539. $this->globals[ $this->attr["name"] ] = $cdata;
  540. break;
  541. case "parameter":
  542. if (isset($this->parameter) && $this->attr["type"] != "array") {
  543. $this->parameter->setvalue( $cdata, $this->attr["name"] );
  544. }
  545. break;
  546. case "element":
  547. if (isset($this->parameter)) {
  548. $this->parameter->setvalue( $cdata, $this->attr["name"] );
  549. }
  550. break;
  551. } // switch
  552. }
  553. // .....................................................................
  554. /** Method invoked when a tag is closed */
  555.  
  556. function tag_close($parser, $tag) {
  557. switch ($tag) {
  558. case "setting":
  559. $this->settings[] = $this->setting;
  560. unset($this->setting);
  561. break;
  562. case "parameter":
  563. if (isset($this->setting) && isset($this->parameter)) {
  564. $this->setting->addparameter($this->parameter->name, $this->parameter);
  565. unset($this->parameter);
  566. }
  567. break;
  568. } // switch
  569. $this->tag = "";
  570. $this->attr = array();
  571. }
  572. // .....................................................................
  573. /**
  574. * Parse the application XML which is provided.
  575. * @param string $xml The XML content to parse for the application.
  576. */
  577. function parse($xml) {
  578. xmlparser::parse($xml);
  579. if (!$this->valid_xml) {
  580. $this->valid = false;
  581. }
  582. }
  583.  
  584. } // application class
  585. // ----------------------------------------------------------------------
  586.  
  587. /**
  588. * Return the index of the given named setting, or -1 if not found.
  589. * @param object $app The application object to scan
  590. * @param string $settingname The name of the setting in $app
  591. * @return integer The index of the setting in $app
  592. */
  593. function get_settingindex($app, $settingname) {
  594. $theix = -1;
  595. for ($ix = 0; $ix < count($app->settings); $ix++) {
  596. $setting = $app->settings[$ix];
  597. if (is_object($setting)) {
  598. if ($setting->getparameter("name") == $settingname) {
  599. $theix = $ix;
  600. break;
  601. }
  602. }
  603. }
  604. return $theix;
  605. }
  606. // ----------------------------------------------------------------------
  607. ?>

Documentation generated by phpDocumentor 1.3.0RC3