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

Documentation generated by phpDocumentor 1.3.0RC3