The Graph_Line class is an independent class that can be used to draw simple line graphs. Consider this class to be experimental, the interface will change in future versions. It will also have less bugs.
classname | Serialization helper: The name of this class. |
title | Title of the current graph |
title col | Color of the title |
xlabel | Text description of the x axis |
xlabel col | Color of this description |
ylabel | Text description of the y axis |
ylabel col | Color of this description |
xgridlines | Number of grid lines to draw (x axis) |
ygridlines | Number of grid lines to draw (y axis) |
grid col | Color to use for these lines |
width | Size of the graph image (width) |
height | Size of the graph image (height) |
fg | Foreground color |
bg | Background color |
|
image | Image handle |
numx | Length of longest lines array |
maxy | Global maximum y value |
miny | Global minimum y value |
lines | Array of arrays of plot points |
line colors | Array of plot color names |
islegend | Flag: Do we have a legend? |
legendlabels | Legend label colors and texts |
xoffset | rightshift for left/top corner |
yoffset | downshift for left/top corner |
xunderset | leftshift for bottom/right corner |
yunderset | upshift for bottom/right corner |
numxlabels | Number of tick marks along x Axis |
numylabels | Number of tick marks along y Axis |
xlabels | Label texts for x Axis |
ylabels | Label texts for y Axis |
colors | Color dictionary |
|
Start a new line graph with the given title, x- and y-Axis labels and of the given width and height. All parameters are optional from right to left. The default title, ylabel and xlabel values are empty (no labels are drawn), the default width and height are 500 and 200 pixels.
Label the y-axis of the result graph numerically with $number many labels. Text labels take precedence over numeric labels.
Label the x-axis of the result graph numerically with $number many labels. Text labels take precedence over numeric labels.
$labels is an array of strings. These strings are used to label the y-axis. If this function is being used, numeric labels cannot be used on this axis.
$labels is an array of strings. These strings are used to label the x-axis. If this function is being used, numeric labels cannot be used on this axis.
Draw a grid of $xnum by $ynum lines.
Create a color named $name with the given RGB values in the color dictionary. The following default colors are in the color dictionary: "black" (0,0,0), "white" (255,255,255), "red" (255,0,0), "green" (0,255,0), "blue" (0,0,255), "yellow" (255,255,0), "magenta" (255,0,255), "cyan" (0,255,255).
Plot the y-values in the array named points in the given color and create a matching legend entry with the given name. The name is optional; if it is missing, no legend entry is being created. If no plot() ever created a legend entry, no legend is created, freeing additional space at the right border of the resulting plot. The color is optional; if it is missing, the foreground color is used.
Use this function to emit the resulting image, content-type header and all.
Draw the title $title and reserve an appropriate amount of border space for the title.
Draw the y-axis label and reserve an appropriate amount of border space for the label.
Draw the x-axis label and reserve an appropriate amount of border space for the label.
Create the default color dictionary with the eight standard colors: "black" (0,0,0), "white" (255,255,255), "red" (255,0,0), "green" (0,255,0), "blue" (0,0,255), "yellow" (255,255,0), "magenta" (255,0,255), "cyan" (0,255,255).
This function does all the work.
Use Graph_Line directly to draw line graphs. This example will draw a line graph with random numbers.
<?php
include("graph.inc");
srand(time());
for ($i=0; $i<40; $i++) {
$a[$i] = rand(0, 10);
$b[$i] = rand(0, 10);
}
$g = new Graph_Line;
$g->start(500, 200, "Random Graph"); // set it up
$g->ynum_labels(10); // numeric and alpha labels
$g->setxlabels(array("start", "middle", "end"));
$g->grid(10, 10); // a grid
$g->plot($a, "red", "a data"); // plot the data
$g->plot($b, "blue", "b data");
$g->draw(); // create image
?>
Sql_Query will generate a query form for simple table queries: A list of field names, comparision operators and input fields is presented. The user may search for any values in any of the presented columns using SQL standard operators. Multiple query conditions are possible and these conditions can be joined using AND and OR operations.
The number of query conditions can be made variable. If so, the user may shrink and grow the query widget using the appropriate buttons.
All button labels and other messages of the interface are variable and held in language dictionaries. Currently, de and en dictionaries are provided.
classname | Serialization helper: The name of this class. |
persistent_slots | Serialization helper: Names of all persistent slots |
conditions | Number of query conditions |
input_size | Visible width of input fields |
input_max | Useable width of input fields |
method | Form method to GET or POST the form |
lang | Language dictionary to use |
translate | Flag: translate column names |
container | Flag: create a master container |
variable | Flag: create resize buttons |
|
dict | The GUI language dictionary. |
compare | SQL comparison function dictionary.
|
Initialization function. Currently empty.
The function will draw the SQL Query selection form. All
variables in the form will start with the prefix $base
and
have numeric indices appended after an underline character. It
is possible to have multiple Sql_Query instances on a single
page, if they use different base characters.
The function must know the field names of the SQL table that is
to be queried. $option
can be either a simple array of
these field names ($translate
set empty) or a hash field
name to long name ($translate
set to on
).
All tags in the generated form are tagged with a CSS stylesheet
class, if $class
is set to a CSS classname. $class
is
optional and if it is left empty, no class attributes are
generated. $target
is the URL of the SQL Query form target.
It is optional and if it is left empty, a self referencing form
is generated (recommended).
When the form()
generated page is submitted, a lot of
parameters have to be evaluated and transformed into a SQL
where condition matching the user selections. The
where()
function takes care of all this; it just needs to
be told which $base
prefix has been used in the form()
call.
The $incr
parameter is optional and determines how many
query condition rows are added or subtracted when the "More"
and "Fewer" buttons are used. The default value is 1.
The function returns a string which can be successfully used behind a "where" keyword in a SQL query.
This function does all the work for where()
, but does not
resize the query condition window.
The Sql_Query
class can be used directly. It is more useful
when made persistent, so it is recommended that you add the line
require("sqlquery.inc")
to your prepend.php3
file
where indicated in that file.
See the Table class in this section for a nice method to display and format query results. See the DB_Sql class (a core class) for a nice method to connect to databases.
The following code fragment is quite large, but contains a complete and working example using the Sql_Query, DB_Sql and Table classes to query a database table.
<?php
// We require() sqlquery.inc and table.inc in prepend.inc
// to make this example work!
page_open(array("sess" => "Poe_Session"));
$db = new DB_Poe; // That's a DB_Sql subclass.
$t = new Table; // For formatting results
$t->heading = "on"; // We want table headings..
?>
<html>
<head><title>Testseite</title>
<style type="text/css"><!--
h1 { font-family: arial, helvetica, sans-serif; color: #d33e30 }
table.test { background-color: #eeeeee }
th.test { font-family: arial, helvetica, sans-serif }
td.test { font-family: arial, helvetica, sans-serif }
table.query { background-color: #cccccc }
td.query { font-face: arial, helvetica, sans-serif }
--></style>
</head>
<body bgcolor="#ffffff">
<h1>Testpage</h1>
<?php
// the following fields are selectable
$field = array(
"username" => "Login Name",
"password" => "Password",
"perms" => "Permissions"
);
// When we hit this page the first time,
// there is no $q.
if (!isset($q)) {
$q = new Sql_Query; // We make one
$q->conditions = 1; // ... with a single condition (at first)
$q->translate = "on"; // ... column names are to be translated
$q->container = "on"; // ... with a nice container table
$q->variable = "on"; // ... # of conditions is variable
$q->lang = "en"; // ... in English, please
$sess->register("q"); // and don't forget this!
}
// When we hit that page a second time, the array named
// by $base will be set and we must generate the $query.
// Ah, and don't set $base to "q" when $q is your Sql_Query
// object... :-)
if (isset($x)) {
$query = $q->where("x", 1);
}
// In any case we must display that form now. Note that the
// "x" here and in the call to $q->where must match.
// Tag everything as a CSS "query" class.
$q->form("x", $field, "query);
printf("<hr>");
// Do we have a valid query string?
if ($query) {
// Show that condition
printf("Query Condition = %s<br>\n", $query);
// Do that query
$db->query("select * from auth_user where ". $query);
// Dump the results (tagged as CSS class test)
printf("Query Results = %s<br>\n", $db->num_rows());
$t->show_result($db, "test");
}
page_close();
?>
</body>
</html>
The Table class is a neat way to format two-dimensional associative arrays of data or the results of a database query into a table. Table and its subclasses allow you to simply pass them either an array or a query result and they spit out the proper HTML for a table containing all the values. Table has some primitive filtering capabilities making it useful even without subclassing, but for the full power of Table you have to write your own subclass.
When used with the check option, it is assumed that the table
is part of a HTML FORM
element. Code is generated to create
an INPUT TYPE=CHECKBOX
element before each table row. The
checkboxes will form an array indexed by row number. The name of
the array will whatever you set the check
instance variable
to.
Exactly one of two types of possible column filtering take place
when each table row is generated. If the fields
instance
variable is set, only the columns keyed by the named fields in
that array are shown in that order. That is, if you fill in the
fields
instance variable with array("a", "c", "e")
,
only the columns a
, c
and e
become part of the
generated table.
If fields
has not been set, all data columns are traversed
with each()
and all columns whose names match the regexp in
filter
are shown in the table. By default, this regular
expression lets through all column names that start with an
alphabetic character and continue with either alphanumeric
characters or "_" (underscore). This default has been
chosen, because the DB_Sql database class uses
mysql_fetch_array()
internally to get data
from the database and this function returns all columns twice
with both a numeric index and proper column names. The default
filter will make all data show up only once and with proper
column names.
A subclass of Table, CSV_Table, is being provided to allow to
create CSV representations of your data with minimal effort. CSV
(comma separated values) can be imported by MySQL's LOAD DATA
INFILE
statement and many spreadsheet import functions.
classname | Serialization helper: The name of this class. |
check | If set, the check option is active. |
filter | A regular expression selecting the columns that are shown. |
fields | A list of colum names that are shown. |
heading | A flag; if set, a heading is being created. |
|
Will format and print the two dimensional array (or hash)
$ary
as a table according to the filtering rules explained
above. If $class
is set, each HTML element will be tagged
as belonging to the named class; this is useful with cascading
style sheets.
Just as show()
, but will show only num
elements
starting at start
.
Will format and print the result set of $db
. $db
is
exspected to be a subclass of DB_Sql
that has just
been sent a query. Table
will grab all available results
from the result set of that query by calling
$db->next_record()
repeatedly and format them
into a table.
Just as show_result()
, but will show only num
elements starting at start
.
Internal function to generate a list of column names.
Internal driver function to generate a table heading row.
Internal driver function to generate a table row.
This function can be overridden by a subclass of Table. It
is called as the very first step in table creation and
should output HTML that opens a table (for example
printf("<table%s>\n", $class?" class=$class":"");
).
This function can be overridden by a subclass of Table. It
is called as the very last step in table creation and
should output HTML that closes a table (for example
printf("<
table>\n");/).
This function can be overridden by a subclass of Table. It is called as the very first step in row creation and should output HTML that opens a table row.
$row
is the current row number. $data
is a hash of
column name/value pairs for that row and $class
is an
optional HTML CSS class name for all generated elements.
This function can be overridden by a subclass of Table. It is called as the very last step in row creation and should output HTML that closes a table row.
This function can be overridden by a subclass of Table. It is called each time a table cell is to be generated.
$row
is the current row number, $cell
is the
current cell number. $key
is the current column name,
$val
is the value of the cell. $class
is the
HTML CSS class of the element that is to be generated.
This function can be overridden by a subclass of Table. It is called each time a table heading cell is to be generated.
$col
is the current column number, $val
is the name
of the column. $class
is the HTML CSS class of the
element that is to be generated.
Table is not automatically included or prepended into each page. Include the table class into the pages that are to use Table. Then create an instance of Table:
<?php
// Include Table
require("table.inc");
// make a Table instance
$t = new Table;
// We want table headings to be printed.
$t->heading = "on";
Now create a two dimensional array or prepare a database query and have table print it.
// Create a database object
$db = new DB_Session;
// create a twodim array called $tab
$tab = $db->metadata("active_sessions");
// print that array
$t->show($tab, "metadata");
// prepare a database query
$db->query("select * from active_sessions");
// print that result
$t->show_result($db, "data");
The form class (sometimes called OOH Forms) is a convenience library for dealing with html forms. It provides Javascript and server-side form validation, and is customizable and extensible.
The OOH Forms library consists of five files: oohforms.inc
of_checkbox.inc of_radio.inc of_select.inc
of_text.inc of_textarea.inc
. oohforms.inc
automatically includes the others. You may wish to modify this so you
can manually include the files for just the form elements you use. Or
you may wish to cut and paste the contents of the element files into
oohforms.inc
to save the overhead of multiple includes.
Determining the appropriate configuration of the files for your site
is left an exercise for the reader; for most purposes
require("oohforms.inc")
will suffice.
In general, the structure of a page that uses oohforms is as follows:
require("oohforms.inc"); // include the library
$f = new form; // create a form object
$f->add_element(...); // set up form elements
$f->add_element(...);
$f->add_element(...);
if ($submitname) // Is there data to process?
if ($err = $f->validate()) { // Is the data valid?
echo $err; // No; Display error
$f->load_defaults(); // Load form with submitted data
else {
/* Process data */ // Data ok; Do something with it
}
$f->start(...); // Start displaying form
$f->show_element(...); // Show elements
$f->show_element(...);
$f->show_element(...);
$->finish(); // Finish form
There are obviously many variations on this theme, but that covers the basics. Specific methods are documented below.
Outputs the initial <form>
tag and sets up some initial
state needed by the class. All of the arguments are optional, though
you'll usually want to use at least one in order to get Javascript
validation. $jvsname
is an arbitrary string used to link the
Javascript to the form; if it is empty (the default), no Javascript
validation is provided. $method
is the HTTP method used to submit the
form; default is "POST"
. $action
is the URL that receives
the form submission; default is $PHP_SELF
. $target
is the
frame target for the form results; default is _self
.
Outputs the any hidden fields that were added to the form, the
final </form>
tag, then the Javascript validation
function (if necessary). $after
and $before
are both
optional; if either is a nonempty string it is output as additional
Javascript to be run on submission of the form, either before or after
the validation code. Though the order of the arguments may seem
counterintuitive, it makes the common case easier to type; in general
you'll want to wait until after the validation has taken place to do
anything fancy with Javascript. Note that unlike with validation, OOH
Forms has no way of giving you server side functionality equivalent to
the Javascript you use here.
add_element
is used to define the attributes of a
particular form element so that the other class methods can use and
manipulate it properly. add_element
takes exactly one
argument: an associate array whose key value pairs are used to
define the form element type and it's various attributes. Some of
these attributes correspond to html attributes, while others are
needed for the value added features of oohforms. The attributes and
the syntax and semantics of the values they take are documented below;
note that not all element types use all of the attributes
The type of element this is; can be "submit"
, "hidden"
,
"text"
, "textarea"
, "select"
, "radio"
,
"checkbox"
, or "file"
.
A string naming this element. This name will be used as an
argument to other methods and will be the name=""
value in the
generated html (and hence the variable name in PHP). Do not
append []
to the name if you want an array valued element; set
the multiple
attribute instead.
The default value of this form element. If the form element has
the multiple
attribute set, value
can be an array. If the
this is a select
element, value
can refer to either the
textual name (label
in the options
array) or the submission
value (value
in options
).
A flag to tell oohforms to assume this element is array valued.
The use of this flag is most straightforward with select
elements,
but it can be use with text
and checkbox
elements as well.
See the show_element
documentation for more information
about how oohforms deals with such elements.
Extra html code that is inserted verbatim into the opening form
tag. For select
elements, the extra html goes into the
select
tag, not the option
tags.
For text
elements, used to set the html size attribute that
gives the width in characters of the text entry box. For select
elements, the size (number of options visible at once) of the
selection box. Validation is only performed on select
elements
if size
is set to 1, since select
validation doesn't make
much sense if you can see multiple options at once. For file
elements, the maximum size file upload to accept.
If set for a text
element, renders the html as a password
element, i.e. entry displays as asterisks.
If set for a submit
element, convert to an image element and
use the value of src
as the source URL for the image.
Used verbatim as the maxlength html attribute in text
elements.
If length_e
is set, this is the minimum length
text
element entry accepted by the validator.
If set, validate the text
element to assure it has at least
minlength
characters. The value of length_e
is the
error string to be used in the event of failed validation.
If set, perform validation on a text
, radio
, or
select
element. For a text
element, validation assures a
match with valid_
regex. radio
element validation
assures that one of the options in the group has been chosen.
select
validation only works for select
elements with
multiple
unset and size
equal to 1; the validator will not
accept the first option of accept menu, assuming that it is some sort
of prompt (e.g. "Please select an item"). In all cases, the value of
valid_e
is the error string used for failed validations.
Regular expression used to validate entry into a test field if
valid_e
is set. Note that if you must use ^...$ if you
want the regex to match the whole entry.
If set, regex matching is case insensitive.
Only used for a checkbox
element that does not have
multiple
set. If checked
is set, the element will display
as checked.
Used verbatim as the rows=
element in a textarea
element.
Used verbatim as the cols=
element in a textarea
element.
Used verbatim as the wrap=
element in a textarea
element.
Array of options to be displayed in a select
element. If the
elements of the array are simple values (strings or numbers), they are
simply displayed verbatim and used as the value for that particular
option. The elements may themselves be associate arrays with keys
"label"
and "value"
. In that case, the value of
"label"
is displayed and the value of "value"
is used on
submission.
Examples:
$f->add_element(array("type"=>"text",
"name"=>"foo",
"valid_regex"=>"^[a-z]*$",
"valid_e"=>"Letters only",
"icase"=>1,
"value"=>"bar"));
$f->add_element(array("type"=>"checkbox",
"name"=>"compress",
"multiple"=>1));
$f->add_element(array("type"=>"textarea",
"name"=>"comment",
"rows"=>6,
"cols"=>40,
"value"=>""));
$o = array(array("label"=>"Please Select","value"=>0),
array("label"=>"Apple","value"=>1),
array("label"=>"Orange","value"=>2),
array("label"=>"Pear","value"=>3),
array("label"=>"Grape","value"=>4));
$f->add_element(array("type"=>"select",
"name"=>"menu",
"options"=>$o,
"size"=>1,
"valid$lowbar;e"=>"Please select a fruit",
"value"=>"apple"));
Outputs the form element named $name
. Usually, the second
argument is not used. It is always necessary for radio
elements
and checkbox
elements with the multiple
attribute set, since
many of these may have the same name. It also must be used for
submit
elements to label the submission button; the value
attribute is not used for submit
elements. For other elements
that may be array valued (notably text
elements) multiple calls
to show_element will show successive values.
Sets the default value of form elements to the value of the PHP variables with the same name. This is generally used to redisplay a form with the same values which were submitted. The argument is optional; if given it is an array of element names; only these elements ares affected.
Validates a form submission. If all of the elements are valid,
return $result
, otherwise return the relevant error message (the
valid_e
or length_e attribute of some form
element). $result
defaults to false
. The second argument
is also optional; it is an array of names of elements to validate.
Freezes the form elements whose names are given in the array passed as the argument. If no argument is given, freeze all of the elements. Frozen elements are rendered as plain, static html rather than form widgets. This static rendering is accompanied by appropriate hidden elements to simulate the affect of using the unfrozen version of the element.
Since OOH Forms is object oriented, it can be easily customized by
extending the classes that define the element types. In general, you
must make sure your derived class has a constructor and you may
override any of the self_* functions of
of_element
. The source for the existing elements is the
best documentation for how to do this properly, but a few general
notes follow.
Display an instance of this element unfrozen. $val
is the
$value
argument of show_element
if there was one;
$which
can be used as an index for array valued elements; it is
equal to the number of times show_element
has been called
for this element previously. This function must return the number of
hidden tags output.
Display an instance of this element frozen. In addition to the html to show the frozen element, you must output tags for hidden fields to duplicate the effect of submitting an unfrozen element of this type. The function must return the number of hidden tags output;
Validate $val
for this element. If it is valid, return false
,
otherwise return the relevant error string.
Print out Javascript code to validate this element.
$ndx_array
is an array of the indices of the elements to
be validated as used in the Javascript form.element[] array. This is
needed since the extra []
in array valued element names confuses
Javascript.
Set the default value for this element to $val
. Usually the
default definition of this function, which just copies $val
to
$this->value
is all that is needed, but there may be special
cases that need to do something else. See the implementation of the
checkbox element for an example.
The Tree class can render tree structures such as directory hierarchies and menu structures as HTML. The structure must be given to Tree as an nested array of arrays of arbitrary depth.
The idea of Tree is, that there are several mathematical models a tree could be viewed: One model is a data structure like nested arrays or a pointer structure from where you can print multidimensional graphics and can do other neat things like deleting one part of the tree or inserting a whole subtree. But you can also imagine a tree as a one dimensional string or as a sequence of function calls (which is nearly the same in the mathematical sense).
To generate HTML-code from a tree-structure it is like this: You need at the end a one-dimensional string, which tells the browser what to do. The Tree class assists you in generating this string in this way, that it will go through the whole tree and call several functions on every stage trough the way. It will be your task to change the functions, so that a nice layout will be generated.
classname | Serialization helper: The name of this class. |
delimiter | a char for truncating the "path" |
tree | an array of an array of an array |
outp | the "output" |
prfx, sufx, flag | internal - some helpers to create outp
|
This function is completely user driven! You have to create an array with the structure described below. See the example for details.
Don't be shy to create some own functions which are called by
build_tree()
- e.g. for recursive calls.
This is the most important function of this class. It will call the output functions in the right order with the correct parameters.
All variables are optional. The parameters are perhaps useful, if you want to display only partial trees, but this is not supported now.
This function is mostly used internally, but could be useful
for you to generate $this->tree
. This function generates
a PHP3 associate array-index string from a path, which is also
a string but truncated by $this->delimiter
. If $key
is given, it will be added to $path
(minds empty path and
so on).
Example:
$t->delimiter="/";
$path= "usr/local/lib";
## $path must be given as a var, because it is called by reference!
$bla = $t->path_to_index($path,"etc");
## $path is now "usr/local/lib/etc"
## $bla is now ["usr"]["local"]["lib"]["etc"]
This function isn't used internally, but could be useful for you during generating the output tree. It will remove one from the depth of the path.
Example:
$t->delimiter="/";
$path= "usr/local/lib";
$bla = $t->path_to_parent($path);
## $path is now "usr/local"
## $bla is now ["usr"]["local"]
This function is the 'non-call-by-reference-version' of
path_to_index
. It will add the $key to
the path and return it.
This function is the 'non-call-by-reference-version' of
path_to_parent
. It will find the
parent of path and return it.
This function is the 'non-call-by-reference-version' of
path_to_index()
. It will return the
associate key to the tree described by path.
This function is called by go_trough_tree()
at the beginning of the output of a tree.
All *tree
-functions are called by go_trough_tree()
,
but it's your turn, to give them a nice layout. I think it is possible
to generate nearly every kind of tree-layout with this. Have a look at
the variables: E.g. $depth
makes it possible to handle every
"level" in another manner.
This function is called by go_trough_tree()
at the beginning of the output of a tree.
It is called every time, when go_trough_tree()
will call itself recursively. You could also say it is called, when
the current item has a successor.
This function is called, when the current item has no successor.
This function is the "opposite" of growtree()
. It is
called every time, when the current item was the last item in this
sub-list.
Called when leaving tree.
As said above, before you call go_trough_tree()
,
first $tree
must be generated.
$tree
consists of nested arrays of arbitrary depth. An example:
$t= new Tree;
$t->tree = array(
"usr" => array(
0 => "allowed",
"lib" => "forbidden",
"local" => "allowed",
"bin" => "forbidden",
"etc" => array(
0 => "allowed",
"hosts" => "forbidden",
"mailcap"=> "allowed"
),
"var" => "allowed",
"tmp" => "allowed"
),
"root" =>"forbidden"
);
$t->go_through_tree();
print $t->outp;
This is a completely recursive structure and I think, it is clear, how to create it with a recursive call of a function. If not, see the example below.
One little quirk has to be explained, because it is a little bit confusing: the array name 0 (zero) is used for the value of the parent element. As shown in the example, an element with children (for example "etc") cannot have attributes (such as "allowed"). Instead the value of this element is stored in a pseudo-child named 0. If this element is not present, it will have the value "Array" (perhaps something that should be changed).
The output of this example if you don't change the output-functions will look like this:
/
^---- usr->'allowed' : 'usr' (1) [1/2]
| ^---- lib->'forbidden' : 'usr^lib' (2) [2/7]
| O---- local->'allowed' : 'usr^local' (2) [3/7]
| O---- bin->'forbidden' : 'usr^bin' (2) [4/7]
| O---- etc->'allowed' : 'usr^etc' (2) [5/7]
| | ^---- hosts->'forbidden' : 'usr^etc^hosts' (3) [2/3]
| | \--- mailcap->'allowed' : 'usr^etc^mailcap' (3) [3/3]
| O---- var->'allowed' : 'usr^var' (2) [6/7]
| \--- tmp->'allowed' : 'usr^tmp' (2) [7/7]
\--- root->'forbidden' : 'root' (1) [2/2]
Looks a bit confusing. From left to right the fields are
path_to_*
-functions)
My example is just going trough the directory structure of your hard disk.
The following code could read it:
class dir_Tree extends Tree {
var $classname = "dir_Tree";
var $delimiter="/";
var $tdat;
function build_tree ($path=".") {
$this->tree=$this->recurs_dir($path,0);
}
## This example code can read and output 1000 directory entries with
## many subdirs in about 20 seconds on my system (P200, 64 MB);
## 220 dir entries with a maximum depth of 4 are read in 2 seconds.
## This is ok. :)
function recurs_dir ($path,$depth) {
GLOBAL $flap_out;
$d=opendir($path);
while ( $name=readdir($d) ) {
$pathname=$path . $this->delimiter . $name;
if (is_dir($pathname) && !ereg("\.\.?",$pathname)) {
if (isset($flap_out[$pathname])) {
$array[$name]=$this->recurs_dir($pathname,$depth+1);
}
# ATTENTION: It is IMPORTANT fill the [0] array
# *after* filling the rest of the array!
$array[$name][0]=$pathname;
} else {
$array[$name]=$pathname;
}
}
closedir($d);
return($array);
}
#################################################
## FLAPPING IN and OUT
## This is used to create an array which includes
## all sub-paths which should be showed
##
function flapping ($path) {
GLOBAL $flap_out;
if ($path) {
if (is_dir($path)) {
if (isset($flap_out[$path])) {
unset($flap_out[$path]);
} else {
$flap_out[$path]=$name;
}
}
}
}
}
$t= new dir_Tree;
$t->flapping($val); ## $val is given by GET-method, see *tree()-functions
$t->build_tree();
$t->go_through_tree();
print $t->outp;
With this code it is very easy to flap in and out whole
parts of the tree. Send the path via GET-method and put
this path in flapping()
. The whole $flap_out
-array must be
persistent (e.g. via session). Perhaps you can program a garbage
collection, which will look into $flap_out
and check for paths that
already exist?
There is one known bug: If a name of a subpath contains the
$delimiter
-string. This cannot be solved correctly and you have
to look for it when you create the tree.
The same thing is with the value [0] (zero) of a sub-array. This element is always used as the attribute of the parent element.
A good tip: when you build your tree recursively then the [0]-index must be filled after the subtree is returned from recursive call. See in the example above what I mean. I think it's a PHP3 specialty.
Also it is possible that not every name could be inserted into the associate index-field (Control-chars etc.), but this is untested.
This is a set of functions, which are used very often by me.
They are so easy, that I now stop describing and simply insert the code. Perhaps the next revision of this set I will replace it with a better description:
<?php
##
## Strings2-Functions
##
## (c) 1998 Alex 'SSilk' Aulbach
##
## These Functions are very practical and if I could program
## C a little bit better it will be placed directly in PHP3.
## But I can't... :-}
##
##
## Have you ever worried about such constructs like
## echo ($faxnumber) ? sprintf("Fax: %s",$faxnumber) : "";
##
## This functionset could help you to replace those constructs by
## p_iftrue($faxnumber,"Fax: %s");
## which is nearly the half of typing and looks more clear and solves
## an error if $faxnumber is unset.
##
function o_iftrue ($val,$str) {
if (isset($val) && $val) {
return(sprintf($str,$val));
}
}
function p_iftrue ($val,$str) {
print o_iftrue($val,$str);
}
##
## Output "One or More"
##
## This function is good if you want to differ a output by number:
## e.g. o_1or2($q->num_rows(),
## "Found only one matching record",
## "Found %s records");
## Will output if num_rows() is 1: "Found only one matching record"
## 200: "Found 200 records"
##
## if $val is empty() or "" a blank string will be returned!
##
function o_1or2 ($val,$str1,$str2) {
if (isset($val) && $val) {
if (1==$val) {
return(sprintf($str1,$val));
} else {
return(sprintf($str2,$val));
}
} else {
return(false);
}
}
function p_1or2 ($val,$str1,$str2) {
print o_1or2 ($val,$str1,$str2);
}
##
## This is for the case, that you want to output something
## if $val is false e.g.
##
## p_0or1($faxnumber,"THERE IS NO FAXNUMBER","Faxnumber: %s");
##
function o_0or1 ($val,$str1,$str2) {
if (empty($val) || !$val) {
if (isset($val)) {
return(sprintf($str1,$val));
} else {
return($str1);
}
} else {
return(sprintf($str2,$val));
}
}
function p_0or1 ($val,$str1,$str2) {
print o_0or1 ($val,$str1,$str2);
}
##
## Replaces all blank-chars with
## This function is used, when you are not willing to let the browser
## break your lines an can be used instead of <NOBR>-Tag
## as very compatible replacement
##
## can also be replaced by a true whitespace which has in
## ISO-latin-1 the code 160
##
function o_nonbsp ($val) {
return(ereg_replace("[[:blank:]\n\r]"," ",$val));
}
function p_nonbsp ($val) {
print o_nonbsp($val);
}
?>