cvs: pearweb /include html_form.php pear-prepend.php /public_html add-author.php add-package.php authors.php index.php list-authors.php
/public_html/doc pear.html pear.xml
| From: | Stig Bakken | Date: | Mon, 17 Jul 2000 22:54:39 +0000 |
| Subject: | cvs: pearweb /include html_form.php pear-prepend.php /public_html add-author.php add-package.php authors.php index.php list-authors.php /public_html/doc pear.html pear.xml |
||
| Groups: | php.pear | ||
| Request: | Send a blank email to php-pear+get-143@lists.php.net to get a copy of this message | ||
ssb Mon Jul 17 15:54:39 2000 EDT
Added files:
/pearweb/include html_form.php
/pearweb/public_html authors.php
Modified files:
/pearweb/include pear-prepend.php
/pearweb/public_html add-author.php add-package.php index.php
list-authors.php
/pearweb/public_html/doc pear.html pear.xml
Log:
* new class: Author (subclasses DB_storage)
* new class: HTML_Form (should go into its own package when it's one)
Index: pearweb/include/pear-prepend.php
diff -u pearweb/include/pear-prepend.php:1.2 pearweb/include/pear-prepend.php:1.3
--- pearweb/include/pear-prepend.php:1.2 Sun Feb 27 20:15:09 2000
+++ pearweb/include/pear-prepend.php Mon Jul 17 15:54:38 2000
@@ -1,23 +1,9 @@
<?php
-define('PEAR_CRED_DOWNLOAD', 0);
-define('PEAR_CRED_UPLOAD', 1);
-define('PEAR_CRED_ADMIN', 2);
+require_once "DB.php";
+require_once "DB/storage.php";
-/*
-function use($package)
-{
- global $USED_PACKAGES;
- if ($USED_PACKAGES[$package]) {
- return;
- }
- if (@include($package . '.php')) {
- $USED_PACKAGES[$package] = true;
- } else {
- die("Unable to load package \"$package\"!");
- }
-}
-*/
+$DSN = "mysql://pear@localhost/pear";
function pageHeader($title = "PEAR: PHP Extension and Add-on Repository",
$style = false)
@@ -43,60 +29,28 @@
}
print "</BODY></HTML>\n";
}
-
-function formMultipleInputRow($data) {
- reset($data);
- while (list($var, $title) = each($data)) {
- global $$var;
- formInputRow($title, $var, $$var);
- }
-}
-
-function formInputCell($name, $default = '', $size = 20) {
- print " <TD><INPUT NAME=\"$name\" VALUE=\"$default\"
SIZE=\"$size\"></TD>\n";
-}
-
-function formInputRow($title, $name, $default = '', $size = 20) {
- print " <TR>\n";
- print " <TH ALIGN=\"right\">$title</TH>";
- formInputCell($name, $default, $size);
- print " </TR>\n";
-}
-function formCheckbox($name, $default = false) {
- print "<INPUT TYPE=\"checkbox\" NAME=\"$name\"";
- if ($default && $default != 'off') {
- print " CHECKED";
+function validate($entity, $field, $value) {
+ switch ("$entity/$field") {
+ case "authors/handle":
+ if (!preg_match('/^[a-z][a-z0-9]+$/i', $value)) {
+ return false;
+ }
+ break;
+ case "authors/name":
+ if (!$value) {
+ return false;
+ }
+ break;
+ case "authors/email":
+ if (!preg_match('/[a-z0-9_\.\+%]@[a-z0-9\.]+\.[a-z]+$', $email)) {
+ return false;
+ }
+ break;
}
- print ">";
-}
-
-function formCheckboxCell($name, $default = false) {
- print " <TD>";
- formCheckbox($name, $default);
- print "</TD>\n";
+ return true;
}
-function formCheckboxRow($title, $name, $default = false) {
- print " <TR>\n";
- print " <TH ALIGN=\"right\">$title</TH>";
- formCheckboxCell($name, $default);
- print " </TR>\n";
-}
-
-function formSubmit($title = 'Submit Changes') {
- print "<INPUT TYPE=\"submit\" VALUE=\"$title\">";
-}
-
-function formSubmitRow($title = 'Submit Changes') {
- print " <TR>\n";
- print " <TD> </TD>\n";
- print " <TD>";
- formSubmit($title);
- print "</TD>\n";
- print " </TR>\n";
-}
-
function invalidHandle($handle) {
if (preg_match('/^[a-z]+-?[a-z]+$/i', $handle)) {
return false;
@@ -125,27 +79,52 @@
return 'invalid URL';
}
-class Author {
- var $handle, $password, $name, $email, $homepage, $created,
- $homepage, $modified, $createdby, $showemail, $registered,
- $credentials, $authorinfo;
- function Author() {
-
+class Author extends DB_storage
+{
+ function Author(&$dbh, $handle = false) {
+ $this->DB_storage("authors", "handle", &$dbh);
+ if ($handle) {
+ $this->setup($handle);
+ }
}
}
-function add_author(&$dbh, $handle, $name, $email, $homepage, $createdby,
- $showemail, $credentials, $authorinfo)
+function authReject($realm, $login_file = false)
{
- $query = 'INSERT INTO authors (handle,password,name,email,homepage,'.
- 'created,modified,createdby,showemail,registered,credentials,'.
- 'authorinfo) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)';
- $stmt = $dbh->prepare($query);
- // XXX not finished
- return $dbh->execute($stmt, array($handle, $passwd, $name, $email,
- $homepage, $created, $modified,
- $modifiedy, $showemail, $registered,
- $credentials, $authorinfo));
+ Header("HTTP/1.0 401 Unauthorized");
+ Header("WWW-authenticate: basic realm=\"$realm\"");
+ if ($login_file) {
+ include($login_file);
+ } else {
+ print "access denied";
+ }
+ exit;
+}
+
+function authRequire($level = 0)
+{
+ global $PHP_AUTH_USER, $PHP_AUTH_PW, $DSN, $dbh, $authorObject;
+
+ $authorObject = new Author(&$dbh, strtoupper($PHP_AUTH_USER));
+ if (DB::isError($authorObject) || md5($PHP_AUTH_PW) != $authorObject->password) {
+ if ($level > 0) {
+ authReject("PEAR administrator");
+ } else {
+ authReject("PEAR maintainer");
+ }
+ }
+}
+
+if (!is_object($dbh)) {
+ $dbh = DB::connect($DSN);
+}
+if (DB::isError($dbh)) {
+ pageHeader("Database Error");
+ print "DB::connect error: ";
+ print DB::errorMessage($dbh);
+ print "<BR>\n";
+ pageFooter();
+ exit;
}
?>
Index: pearweb/public_html/add-author.php
diff -u pearweb/public_html/add-author.php:1.2 pearweb/public_html/add-author.php:1.3
--- pearweb/public_html/add-author.php:1.2 Sun Feb 27 20:15:09 2000
+++ pearweb/public_html/add-author.php Mon Jul 17 15:54:38 2000
@@ -1,36 +1,106 @@
<?php
-pageHeader("PEAR: Add an author");
+require_once "html_form.php";
+authRequire();
+
+$display_form = true;
+
+function displayError($msg)
+{
+ global $errorMsg;
+ $errorMsg .= "<FONT COLOR=\"#CC0000\">$msg</FONT><BR>\n";
+}
+
+$jumpto = "handle";
+
+do {
+ if ($submit) {
+ $required = array("handle", "name", "email");
+ while (list($i, $field) = each($required)) {
+ if (!$$field) {
+ displayError("Please enter $field");
+ $jumpto = $field;
+ break 2;
+ }
+ }
+
+ if (!preg_match("/^[a-z][a-z0-9]+$/i", $handle)) {
+ displayError("Handle must start with a letter and contain ".
+ "only letters and digits.");
+ break;
+ }
+
+ if ($password != $password2) {
+ displayError("Passwords did not match");
+ $password = $password2 = "";
+ break;
+ }
+
+ if (!$password) {
+ displayError("Empty passwords not allowed");
+ break;
+ }
+
+ $handle = strtoupper($handle);
+ $obj = new Author(&$dbh);
+ $err = $obj->insert($handle);
+ if (DB::isError($err)) {
+ displayError("$handle: " . DB::errorMessage($err));
+ $jumpto = "handle";
+ break;
+ }
+
+ $display_form = false;
+ $obj->name = $name;
+ $obj->email = $email;
+ $obj->homepage = $homepage;
+ $obj->showemail = (bool)$showemail;
+ $obj->admin = (bool)$admin;
+ $obj->password = md5($password);
+ }
+} while (0);
+
+if ($display_form) {
+
+ pageHeader("PEAR: Add an author");
+
?>
<H1>Add an author</H1>
<FORM ACTION="<?php echo $PHP_SELF; ?>" METHOD="POST">
<TABLE>
<?php
-
-formInputRow("Handle", "handle", '', 10);
-formInputRow("Name", "name", '', 40);
-formInputRow("Email", "email", '', 40);
-formInputRow("Homepage", "homepage", '', 40);
-
-formCheckboxRow("Show email?", "showemail", '', 40);
-
-print " <TR>\n";
-print " <TH ALIGN=\"right\">Credentials</TH>\n";
-print " <TD>\n ";
-formCheckbox('cred_upload', true);
-print " contributor<BR>\n ";
-formCheckbox('cred_admin');
-print " administrator<BR>\n";
-print " </TD>\n";
-print " </TR>\n";
-formSubmitRow();
+ if ($errorMsg) {
+ print " <TR>\n";
+ print " <TD> </TD>\n";
+ print " <TD><B>$errorMsg</B></TD>\n";
+ print " </TR>\n";
+ }
+
+ $width = 60;
+
+ formInputRow("Handle", "handle", $handle, 12);
+ formInputRow("Name", "name", $name, $width);
+ formInputRow("Email", "email", $email, $width);
+ formInputRow("Homepage", "homepage", $homepage, $width);
+ formCheckboxRow("Show Email Address?", "showemail", (bool)$showemail);
+ formCheckboxRow("Administrator?", "admin", (bool)$admin);
+ formPasswordRow("Password", "password", $password);
+ formTextareaRow("More info", "info", '', $width, 5);
+ formSubmitRow("Add Author");
?></TABLE>
</FORM>
<?php
+
+ if ($jumpto) {
+ print "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\n";
+ print "document.forms[0].$jumpto.focus();\n";
+ print "\n// -->\n</SCRIPT>\n";
+ }
+ pageFooter();
-pageFooter();
+}
?>
Index: pearweb/public_html/add-package.php
diff -u pearweb/public_html/add-package.php:1.1 pearweb/public_html/add-package.php:1.2
--- pearweb/public_html/add-package.php:1.1 Sun Dec 12 04:44:31 1999
+++ pearweb/public_html/add-package.php Mon Jul 17 15:54:38 2000
@@ -1,13 +1,30 @@
<?php
+$t1 = microtime();
+
+include_once "html_form.php";
+
+$t2 = microtime();
+
pageHeader("PEAR: Add a package");
-?>
-<FORM ACTION="<?php echo $PHP_SELF; ?>" METHOD="POST">
+$domains = $dbh->getAssoc("SELECT domain,domain FROM domains");
+$domains[""] = "[root]";
-</FORM>
-<?php
+$form = new HTML_Form($PHP_SELF, "POST");
+$form->addText("name", "Name", "");
+$form->addHidden("hidden1", "foo");
+$form->addHidden("hidden2", "bar");
+$form->addSelect("domain", "Domain", &$domains, '', 1,
'Select Domain');
+$form->addSubmit();
+$form->display();
pageFooter();
+
+$t3 = microtime();
+
+print "t1=$t1<br>\n";
+print "t2=$t2 (".((double)$t2-(double)$t1).")<br>\n";
+print "t3=$t3 (".((double)$t3-(double)$t2).")<br>\n";
?>
Index: pearweb/public_html/index.php
diff -u pearweb/public_html/index.php:1.3 pearweb/public_html/index.php:1.4
--- pearweb/public_html/index.php:1.3 Sun Feb 27 20:17:53 2000
+++ pearweb/public_html/index.php Mon Jul 17 15:54:38 2000
@@ -5,13 +5,15 @@
print "<H1>PEAR: PHP Extension and Add-on Repository</H1>\n";
if ($SERVER_NAME != "pear.php.net") {
- print "<A HREF=\"add-package.php\">ADD NEW
PACKAGE</A><BR>\n";
- print "<A HREF=\"add-author.php\">ADD NEW
AUTHOR</A><BR>\n";
- print "<A HREF=\"list-packages.php\">LIST
PACKAGES</A><BR>\n";
- print "<A HREF=\"list-authors.php\">LIST
AUTHORS</A><BR>\n";
- print "<A HREF=\"domains.php\">DOMAIN
ADMINISTRATION</A><BR>\n";
+ print "<A HREF=\"authors.php\">AUTHORS</A><BR>\n";
+ print "<A HREF=\"packages.php\">PACKAGES</A><BR>\n";
+ print "<A HREF=\"domains.php\">DOMAINS</A><BR>\n";
}
print "<H2><A HREF=\"doc/\">Documentation</A></H2>\n";
+
+$dbh = DB::connect("mysql://pear@localhost/pear");
+$ssb = new Author(&$dbh, "SSB");
+print $ssb->toString();
pageFooter();
Index: pearweb/public_html/list-authors.php
diff -u pearweb/public_html/list-authors.php:1.2 pearweb/public_html/list-authors.php:1.3
--- pearweb/public_html/list-authors.php:1.2 Sun Feb 27 20:15:09 2000
+++ pearweb/public_html/list-authors.php Mon Jul 17 15:54:38 2000
@@ -1,7 +1,5 @@
<?php
-use("DB");
-
pageHeader("PEAR: List packages");
$dbh = DB::Connect("mysql://pear@localhost/pear");
Index: pearweb/public_html/doc/pear.html
diff -u pearweb/public_html/doc/pear.html:1.3 pearweb/public_html/doc/pear.html:1.4
--- pearweb/public_html/doc/pear.html:1.3 Mon Feb 28 08:19:05 2000
+++ pearweb/public_html/doc/pear.html Mon Jul 17 15:54:39 2000
@@ -24,6 +24,10 @@
><H3
CLASS="author"
>Stig Bakken</H3
+><SPAN
+CLASS="releaseinfo"
+>
+ <BR></SPAN
><DIV
CLASS="revhistory"
><TABLE
@@ -41,10 +45,10 @@
><TR
><TD
ALIGN="LEFT"
->Revision $Revision: 1.3 $</TD
+>Revision $Revision: 1.4 $</TD
><TD
ALIGN="LEFT"
->$Date: 2000/02/28 16:19:05 $</TD
+>$Date: 2000/07/17 22:54:39 $</TD
><TD
ALIGN="LEFT"
>Revised by: $Author: ssb $</TD
@@ -60,11 +64,6 @@
><HR></DIV
><P
>PEAR is dedicated to Malin Bakken, born 1999-11-21.</P
-><P
-> This document is incomplete. For now it only contains a brief
- description of PEAR and "Coding Rules and Guidelines". The rules
- and guidelines are initial suggestions, and are open for discussion.
- </P
><DIV
CLASS="section"
><HR><H1
@@ -96,7 +95,7 @@
></H1
><P
> This section describes some rules that are meant to make PEAR code
- available to as many users as possible. If you plan to contribute
+ available to as many users as possible. If you want to contribute
to PEAR, please read this section carefully and follow these rules,
or someone will yell at you. :-)
</P
@@ -113,9 +112,22 @@
CLASS="filename"
>.php</TT
> for
- all files with PHP code (files that when included don't output
- anything, but only define variables, constants, functions or
- classes).
+ all files with PHP code.
+ <DIV
+CLASS="note"
+><BLOCKQUOTE
+CLASS="note"
+><P
+><B
+>Note: </B
+>
+ It is important that your files do not output anything, so watch
+ those extra linefeeds at the end of the files (no more than
+ one!)
+ </P
+></BLOCKQUOTE
+></DIV
+>
</P
><P
> A related set of one or more classes and functions in PEAR are
@@ -128,8 +140,10 @@
this structure maps 1:1 down to the file system, it is
conceptually not a filesystem structure. The structure is based
on the developer's view when writing code, which is the parameters
- to "use" or "import" (PEAR is currently using "include" though).
- An example:
+ to <B
+CLASS="function"
+>use</B
+>. An example:
<DIV
CLASS="informalexample"
><P
@@ -162,20 +176,41 @@
><HR><H3
CLASS="section"
><A
-NAME="pear-funcnames"
->Function and Method Names</A
+NAME="pear-pkgnames"
+>Package Names</A
></H3
><P
-> Functions (not methods), should be named with underscores, like
- this: <TT
-CLASS="function"
->my_function</TT
->. Methods should be named
- with initial lower-case studlycaps like this:
+> The definition of a package in PEAR is file defining one "public"
+ class and possible several "private" ones. Although PHP doesn't
+ have the notion of public classes, PEAR uses this concept. A
+ public class is a class that is available to other packages or
+ the user, a private class is a class that is internal to that
+ package, and that the PHP programmer will normally not deal with
+ directly.
+ </P
+><P
+> All PEAR package files should use the suffix <TT
+CLASS="filename"
+>.php</TT
+>. The class name is the file name
+ without the <TT
+CLASS="filename"
+>.php</TT
+> suffix.
+ </P
+><P
+> For example, the package <SPAN
+CLASS="systemitem"
+>DB/mysql</SPAN
+> would have its code in a
+ file called <TT
+CLASS="filename"
+>mysql.php</TT
+> in a directory called
<TT
-CLASS="function"
->myFunction</TT
->.
+CLASS="filename"
+>DB</TT
+> in a directory in PHP's include path.
</P
></DIV
><DIV
@@ -187,21 +222,138 @@
>Class Names</A
></H3
><P
-> Class names are not as straightforward. PEAR should never have
- name conflicts among its classes (and preferably ditto for
- functions, but that can be solved using static methods in
- classes). Since PHP doesn't have packages or name spaces yet, we
- need to "brute force" it. The solution is currently not too
- pretty, maybe it serves as inspiration for the Zend authors to
- implement name spaces :-).
+> PEAR classes should never have name conflicts. Since PHP doesn't
+ have packages or name spaces yet, it is necessary to enforce a
+ class naming convention that provides a "poor man's name spaces".
+ Hopefully this will serve as an inspiration for the Zend authors
+ to implement name spaces :-).
</P
><P
> The basic class name rule is to use the package name and
- substitute slashes with underscores. The package "DB/mysql" has
- its code in the file "DB/mysql.php" and defines a class called
- "DB_mysql".
+ substitute slashes with underscores. The package <SPAN
+CLASS="systemitem"
+>DB/mysql</SPAN
+> has its code in the file
+ <TT
+CLASS="filename"
+>DB/mysql.php</TT
+> and defines a class called
+ <TT
+CLASS="classname"
+>DB_mysql</TT
+>.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H3
+CLASS="section"
+><A
+NAME="pear-functions"
+>Functions</A
+></H3
+><P
+> At this time, PEAR does not support plain functions. The reason
+ for this is that we want to avoid name space problems where
+ different packages define functions with the same name. One
+ solution could be prefixing each function's name with its package
+ name, but then encapsulating the functions in classes is better.
</P
+><P
+> When PHP gets support for namespaces (some time _after_ the 4.0
+ release), PEAR will support plain functions.
+ </P
+><P
+> If you have a function you want to make available in a PEAR
+ package, make a class based on the package name (Foo/Bar ->
+ Foo_Bar), and add the function as a method there. Example:
+ <DIV
+CLASS="informalexample"
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="programlisting"
+> 1
+ 2 Header("Last-Modified: " . HTTP::Date(getlastmod()));
+ 3 </PRE
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H3
+CLASS="section"
+><A
+NAME="pear-funcnames"
+>Method Names</A
+></H3
+><P
+> Methods should be named with initial lower-case studlycaps like
+ this: <B
+CLASS="function"
+>myFunction()</B
+>.
+ </P
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="AEN63"
+>Variable Names</A
+></H2
+><P
+> Global variables visible to the user should be prefixed with the
+ package name with "/" substituted with "_" (like for class names)
+ and an underscore. If you need global variables that are not to
+ be "visible" to the user, prefix the whole thing with an
+ underscore.
+ </P
+><P
+> Example (let's say this package is Gah/Zonk):
+ <DIV
+CLASS="informalexample"
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><PRE
+CLASS="programlisting"
+> 1
+ 2 <?php
+ 3
+ 4 $Gah_Zonk_errorcodes = array( -1 => "This error",
+ 5 -2 => "That error" );
+ 6 $_Gah_Zonk_cache = array();
+ 7
+ 8 ?>
+ 9 </PRE
+></TD
+></TR
+></TABLE
+><P
+></P
></DIV
+>
+ </P
></DIV
><DIV
CLASS="section"
@@ -209,25 +361,21 @@
CLASS="section"
><A
NAME="pear-errors"
->Returning Errors</A
+>Errors</A
></H2
><P
-> Your code should <I
-CLASS="emphasis"
->never</I
-> use
- <TT
+> Never use <B
CLASS="function"
->exit</TT
-> or <TT
+>exit()</B
+> or <B
CLASS="function"
->die</TT
-> if it
- encounters an error. This would make developers using your code
- unable to catch these errors, handle them or even display their
- own error message. As far as possible, use some way of giving
- errors back to the caller, even if it is just a boolean return
- value.
+>die()</B
+> if
+ your PEAR package encounters an error. Doing this generally makes
+ peoples lives miserable when they try handling errors nicely. Try
+ to always provide a way of telling whether something went wrong
+ and what, be it as simple as returning an error code, or something
+ more fancy.
</P
></DIV
><DIV
@@ -236,13 +384,13 @@
CLASS="section"
><A
NAME="pear-options"
->Depending on Optional Features</A
+>Optional PHP Features</A
></H2
><P
-> PEAR code is meant to be useable with all (reasonable)
- configurations of PHP. Since PHP is very configurable and many of
- its features are optional, this requires extra attention from you
- as a PEAR author to make sure that your code works with different
+> PEAR code should be useable with all (reasonable) configurations
+ of PHP. Since PHP is very configurable and many of its features
+ are optional, this requires extra attention from you as a PEAR
+ author to make sure that your code works with different
configurations.
</P
><P
@@ -258,13 +406,23 @@
CLASS="informalexample"
><P
></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
><PRE
CLASS="programlisting"
-> // If magic_quotes_gpc is enabled, remove those slashes.
-if (ini_get("magic_quotes_gpc")) {
- $arg = stripslashes($arg);
-}
-</PRE
+> 1
+ 2 // If magic_quotes_gpc is enabled, remove those slashes.
+ 3 if (ini_get("magic_quotes_gpc")) {
+ 4 $arg = stripslashes($arg);
+ 5 }
+ 6 </PRE
+></TD
+></TR
+></TABLE
><P
></P
></DIV
@@ -354,40 +512,82 @@
within a function. The included file will inherit the calling
code's scope:
- <DIV
+ <TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+CLASS="EXAMPLE"
+><TR
+><TD
+><DIV
CLASS="example"
><P
><B
>Example 1. file1.php</B
></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
><PRE
CLASS="programlisting"
-> <?php $myglobal = 42; ?>
-</PRE
+> 1
+ 2 <?php $myglobal = 42; ?>
+ 3 </PRE
+></TD
+></TR
+></TABLE
></DIV
+></TD
+></TR
+></TABLE
>
- <DIV
+ <TABLE
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+CLASS="EXAMPLE"
+><TR
+><TD
+><DIV
CLASS="example"
><P
><B
>Example 2. file2.php</B
></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
><PRE
CLASS="programlisting"
-> <?php
-
-class Foo {
- function Foo($arg) {
- if ($arg == 42) {
- include("file1.php");
- }
- }
-}
-
-?>
-</PRE
+> 1
+ 2 <?php
+ 3
+ 4 class Foo {
+ 5 function Foo($arg) {
+ 6 if ($arg == 42) {
+ 7 include("file1.php");
+ 8 }
+ 9 }
+ 10 }
+ 11
+ 12 ?>
+ 13 </PRE
+></TD
+></TR
+></TABLE
></DIV
+></TD
+></TR
+></TABLE
>
</P
><P
Index: pearweb/public_html/doc/pear.xml
diff -u pearweb/public_html/doc/pear.xml:1.4 pearweb/public_html/doc/pear.xml:1.5
--- pearweb/public_html/doc/pear.xml:1.4 Mon Feb 28 08:18:47 2000
+++ pearweb/public_html/doc/pear.xml Mon Jul 17 15:54:39 2000
@@ -10,10 +10,18 @@
<surname>Bakken</surname>
</author>
</authorgroup>
+ <releaseinfo>
+ <comment>
+ This document is incomplete. For now it only contains a brief
+ description of PEAR and "Coding Rules and Guidelines". The rules
+ and guidelines are initial suggestions, and are open for
+ discussion.
+ </comment>
+ </releaseinfo>
<revhistory>
<revision>
- <revnumber>$Revision: 1.4 $</revnumber>
- <date>$Date: 2000/02/28 16:18:47 $</date>
+ <revnumber>$Revision: 1.5 $</revnumber>
+ <date>$Date: 2000/07/17 22:54:39 $</date>
<authorinitials>$Author: ssb $</authorinitials>
</revision>
</revhistory>
@@ -21,12 +29,6 @@
<simpara>PEAR is dedicated to Malin Bakken, born 1999-11-21.</simpara>
- <simpara>
- This document is incomplete. For now it only contains a brief
- description of PEAR and "Coding Rules and Guidelines". The rules
- and guidelines are initial suggestions, and are open for discussion.
- </simpara>
-
<section id="pear-whatis">
<title>What is PEAR?</title>
<simpara>
@@ -48,7 +50,7 @@
<title>Coding Rules and Guidelines</title>
<simpara>
This section describes some rules that are meant to make PEAR code
- available to as many users as possible. If you plan to contribute
+ available to as many users as possible. If you want to contribute
to PEAR, please read this section carefully and follow these rules,
or someone will yell at you. :-)
</simpara>
@@ -56,12 +58,16 @@
<section id="pear-names">
<title>Naming Conventions</title>
- <simpara>
+ <para>
Use the extension <filename role="extension">.php</filename> for
- all files with PHP code (files that when included don't output
- anything, but only define variables, constants, functions or
- classes).
- </simpara>
+ all files with PHP code.
+ <note>
+ <simpara>
+ It is important that your files do not output anything, so watch
+ those linefeeds at the end of files (no more than one!)
+ </simpara>
+ </note>
+ </para>
<para>
A related set of one or more classes and functions in PEAR are
@@ -75,8 +81,7 @@
this structure maps 1:1 down to the file system, it is
conceptually not a filesystem structure. The structure is based
on the developer's view when writing code, which is the parameters
- to "use" or "import" (PEAR is currently using "include" though).
- An example:
+ to <function role="statement">use</function>. An example:
<informalexample>
<literallayout>DB
DB/common
@@ -94,56 +99,126 @@
filesystem structure, as explained above. So there.
</para>
- <section id="pear-funcnames">
- <title>Function and Method Names</title>
+ <section id="pear-pkgnames">
+ <title>Package Names</title>
+ <simpara>
+ The definition of a package in PEAR is file defining one "public"
+ class and possible several "private" ones. Although PHP doesn't
+ have the notion of public classes, PEAR uses this concept. A
+ public class is a class that is available to other packages or
+ the user, a private class is a class that is internal to that
+ package, and that the PHP programmer will normally not deal with
+ directly.
+ </simpara>
<simpara>
- Functions (not methods), should be named with underscores, like
- this: <function>my_function</function>. Methods should be named
- with initial lower-case studlycaps like this:
- <function>myFunction</function>.
+ All PEAR package files should use the suffix <filename
+ role="suffix">.php</filename>. The class name is the file name
+ without the <filename role="suffix">.php</filename> suffix.
</simpara>
+ <para>
+ For example, the package <systemitem
+ role="package">DB/mysql</systemitem> would have its code in a
+ file called <filename>mysql.php</filename> in a directory called
+ <filename>DB</filename> in a directory in PHP's include path.
+ </para>
</section>
<section id="pear-classnames">
<title>Class Names</title>
<para>
- Class names are not as straightforward. PEAR should never have
- name conflicts among its classes (and preferably ditto for
- functions, but that can be solved using static methods in
- classes). Since PHP doesn't have packages or name spaces yet, we
- need to "brute force" it. The solution is currently not too
- pretty, maybe it serves as inspiration for the Zend authors to
- implement name spaces :-).
+ PEAR classes should never have name conflicts. Since PHP doesn't
+ have packages or name spaces yet, it is necessary to enforce a
+ class naming convention that provides a "poor man's name spaces".
+ Hopefully this will serve as an inspiration for the Zend authors
+ to implement name spaces :-).
</para>
<para>
The basic class name rule is to use the package name and
- substitute slashes with underscores. The package "DB/mysql" has
- its code in the file "DB/mysql.php" and defines a class called
- "DB_mysql".
+ substitute slashes with underscores. The package <systemitem
+ role="package">DB/mysql</systemitem> has its code in the file
+ <filename>DB/mysql.php</filename> and defines a class called
+ <classname>DB_mysql</classname>.
</para>
</section>
+
+ <section id="pear-functions">
+ <title>Functions</title>
+ <simpara>
+ At this time, PEAR does not support plain functions. The reason
+ for this is that we want to avoid name space problems where
+ different packages define functions with the same name. One
+ solution could be prefixing each function's name with its package
+ name, but then encapsulating the functions in classes is better.
+ </simpara>
+ <simpara>
+ When PHP gets support for namespaces (some time _after_ the 4.0
+ release), PEAR will support plain functions.
+ </simpara>
+ <para>
+ If you have a function you want to make available in a PEAR
+ package, make a class based on the package name (Foo/Bar ->
+ Foo_Bar), and add the function as a method there. Example:
+ <informalexample>
+ <programlisting>
+Header("Last-Modified: " . HTTP::Date(getlastmod()));
+</programlisting>
+ </informalexample>
+ </para>
+ </section>
+
+ <section id="pear-funcnames">
+ <title>Method Names</title>
+ <simpara>
+ Methods should be named with initial lower-case studlycaps like
+ this: <function>myFunction</function>.
+ </simpara>
+ </section>
+ </section>
+
+ <section>
+ <title>Variable Names</title>
+ <simpara>
+ Global variables visible to the user should be prefixed with the
+ package name with "/" substituted with "_" (like for class names)
+ and an underscore. If you need global variables that are not to
+ be "visible" to the user, prefix the whole thing with an
+ underscore.
+ </simpara>
+ <para>
+ Example (let's say this package is Gah/Zonk):
+ <informalexample>
+ <programlisting>
+<?php
+
+$Gah_Zonk_errorcodes = array( -1 => "This error",
+ -2 => "That error" );
+$_Gah_Zonk_cache = array();
+
+?>
+</programlisting>
+ </informalexample>
+ </para>
</section>
<section id="pear-errors">
- <title>Returning Errors</title>
+ <title>Errors</title>
<simpara>
- Your code should <emphasis>never</emphasis> use
- <function>exit</function> or <function>die</function> if it
- encounters an error. This would make developers using your code
- unable to catch these errors, handle them or even display their
- own error message. As far as possible, use some way of giving
- errors back to the caller, even if it is just a boolean return
- value.
+ Never use <function>exit</function> or <function>die</function> if
+ your PEAR package encounters an error. Doing this generally makes
+ peoples lives miserable when they try handling errors nicely. Try
+ to always provide a way of telling whether something went wrong
+ and what, be it as simple as returning an error code, or something
+ more fancy.
</simpara>
</section>
<section id="pear-options">
- <title>Depending on Optional Features</title>
+ <title>Optional PHP Features</title>
<simpara>
- PEAR code is meant to be useable with all (reasonable)
- configurations of PHP. Since PHP is very configurable and many of
- its features are optional, this requires extra attention from you
- as a PEAR author to make sure that your code works with different
+ PEAR code should be useable with all (reasonable) configurations
+ of PHP. Since PHP is very configurable and many of its features
+ are optional, this requires extra attention from you as a PEAR
+ author to make sure that your code works with different
configurations.
</simpara>
<para>
Index: pearweb/include/html_form.php
+++ pearweb/include/html_form.php
<?php
// {{{ constants
if (!defined("HTML_FORM_TEXT_SIZE")) {
define("HTML_FORM_TEXT_SIZE", 20);
}
if (!defined("HTML_FORM_PASSWD_SIZE")) {
define("HTML_FORM_PASSWD_SIZE", 10);
}
if (!defined("HTML_FORM_TEXTAREA_HT")) {
define("HTML_FORM_TEXTAREA_HT", 5);
}
if (!defined("HTML_FORM_TEXTAREA_WT")) {
define("HTML_FORM_TEXTAREA_WT", HTML_FORM_TEXT_SIZE);
}
// }}}
class HTML_Form {
// {{{ properties
/** ACTION attribute of <FORM> tag */
var $action;
/** METHOD attribute of <FORM> tag */
var $method;
/** NAME attribute of <FORM> tag */
var $name;
/** an array of entries for this form */
var $fields;
/** DB_storage object, if tied to one */
var $storageObject;
// }}}
// {{{ constructor
function HTML_Form($action, $method = 'GET', $name = '') {
$this->action = $action;
$this->method = $method;
$this->name = $name;
$this->fields = array();
}
// }}}
// {{{ addText()
function addText($name, $title, $default, $size = HTML_FORM_TEXT_SIZE) {
$this->fields[] = array("text", $name, $title, $default, $size);
}
// }}}
// {{{ addPassword()
function addPassword($name, $title, $default, $size = HTML_FORM_PASSWD_SIZE) {
$this->fields[] = array("password", $name, $title, $default, $size);
}
// }}}
// {{{ addCheckbox()
function addCheckbox($name, $title, $default) {
$this->fields[] = array("checkbox", $name, $title, $default);
}
// }}}
// {{{ addTextarea()
function addTextarea($name, $title, &$default,
$width = HTML_FORM_TEXTAREA_WT,
$height = HTML_FORM_TEXTAREA_HT) {
$this->fields[] = array("textarea", $name, $title, &$default, $width, $height);
}
// }}}
// {{{ addSubmit
function addSubmit($name = "submit", $title = "Submit Changes") {
$this->fields[] = array("submit", $name, $title);
}
// }}}
// {{{ addReset()
function addReset($title = "Discard Changes") {
$this->fields[] = array("reset", $title);
}
// }}}
// {{{ addSelect()
function addSelect($name, $title, $entries, $default = '', $size = 1,
$blank = '', $multiple = false) {
$this->fields[] = array("select", $name, $title, &$entries, $default, $size,
$blank, $multiple);
}
// }}}
// {{{ addRadio()
function addRadio($name, $title, $value, $default) {
$this->fields[] = array("radio", $name, $title, $value, $default);
}
// }}}
// {{{ addImage()
function addImage($name, $src) {
$this->fields[] = array("image", $name, $src);
}
// }}}
// {{{ addHidden()
function addHidden($name, $value) {
$this->fields[] = array("hidden", $name, $value);
}
// }}}
// {{{ start()
function start($action, $method = 'GET', $name = '') {
print "<FORM ACTION=\"$action\" METHOD=\"$method\"";
if ($name) {
print " NAME=\"$name\"";
}
print ">";
}
// }}}
// {{{ end()
function end() {
$fields = array();
reset($this->fields);
while (list($i, $data) = each($this->fields)) {
if ($data[0] == 'reset') {
continue;
}
$name = $data[1];
}
$this->displayHidden("_fields", implode(":", $fields));
print "</FORM>";
}
// }}}
// {{{ displayText()
function displayText($name, $default = '', $size = HTML_FORM_TEXT_SIZE) {
print "<INPUT NAME=\"$name\" VALUE=\"$default\"
SIZE=\"$size\">";
}
// }}}
// {{{ displayTextRow()
function displayTextRow($name, $title, $default = '', $size = HTML_FORM_TEXT_SIZE) {
print " <TR>\n";
print " <TH ALIGN=\"right\">$title</TH>";
print " <TD>";
$this->displayText($name, $default, $size);
print "</TD>\n";
print " </TR>\n";
}
// }}}
// {{{ displayPassword()
function displayPassword($name, $default = '', $size = HTML_FORM_PASSWD_SIZE) {
print "<INPUT NAME=\"$name\" TYPE=\"password\"
VALUE=\"$default\" SIZE=\"$size\">";
}
// }}}
// {{{ displayPasswordRow()
function displayPasswordRow($name, $title, $default = '', $size =
HTML_FORM_PASSWD_SIZE) {
print "<TR>\n";
print " <TH ALIGN=\"right\">$title</TH>\n";
print " <TD>";
$this->displayPassword($name, $default, $size);
print " repeat: ";
$this->displayPassword($name."2", $default, $size);
print "</TD>\n";
print "</TR>\n";
}
// }}}
// {{{ displayCheckbox()
function displayCheckbox($name, $default = false) {
print "<INPUT TYPE=\"checkbox\" NAME=\"$name\"";
if ($default && $default != 'off') {
print " CHECKED";
}
print ">";
}
// }}}
// {{{ displayCheckboxRow()
function displayCheckboxRow($name, $title, $default = false) {
print " <TR>\n";
print " <TH ALIGN=\"right\">$title</TH>";
print " <TD>";
$this->displayCheckbox($name, $default);
print "</TD>\n";
print " </TR>\n";
}
// }}}
// {{{ displayTextarea()
function displayTextarea($name, $default = '', $width = 40, $height = 5) {
print "<TEXTAREA NAME=\"$name\" COLS=\"$width\"
ROWS=\"$height\">";
print $default;
print "</TEXTAREA>";
}
// }}}
// {{{ displayTextareaRow()
function displayTextareaRow($name, $title, $default = '', $width = 40, $height = 5) {
print " <TR>\n";
print " <TH ALIGN=\"right\">$title</TH>\n";
print " <TD>";
$this->displayTextarea($name, &$default, $width, $height);
print "</TD>\n";
print " </TR>\n";
}
// }}}
// {{{ displaySubmit()
function displaySubmit($title = 'Submit Changes', $name = "submit") {
print "<INPUT NAME=\"$name\" TYPE=\"submit\"
VALUE=\"$title\">";
}
// }}}
// {{{ displaySubmitRow()
function displaySubmitRow($name = "submit", $title = 'Submit Changes') {
print " <TR>\n";
print " <TD> </TD>\n";
print " <TD>";
$this->displaySubmit($title, $name);
print "</TD>\n";
print " </TR>\n";
}
// }}}
// {{{ displayHidden()
function displayHidden($name, $value) {
print "<INPUT TYPE=\"hidden\" NAME=\"$name\"
VALUE=\"$value\">";
}
// }}}
// {{{ displaySelect()
function displaySelect($name, $entries, $default = '', $size = 1,
$blank = '', $multiple = false) {
print " <SELECT NAME=\"$name\"";
if ($size) {
print " SIZE=\"$size\"";
}
if ($multiple) {
print " MULTIPLE";
}
print ">\n";
if ($blank) {
print " <OPTION VALUE=\"\">$blank\n";
}
while (list($val, $text) = each($entries)) {
print ' <OPTION ';
if ($default && $default == $val) {
print 'SELECTED ';
}
print "VALUE=\"$val\">$text\n";
}
print " </SELECT>\n";
}
// }}}
// {{{ displaySelectRow()
function displaySelectRow($name, $title, &$entries, $default = '', $size = 1,
$blank = '', $multiple = false)
{
print " <TR>\n";
print " <TH ALIGN=\"right\">$title:</TH>\n";
print " <TD>\n";
$this->displaySelect($name, &$entries, $default, $size, $blank, $multiple);
print " </TD>\n";
print " </TR>\n";
}
// }}}
// XXX missing: displayRadio displayRadioRow displayReset
// {{{ display()
function display() {
$this->start();
print "<TABLE>\n";
reset($this->fields);
$hidden = array();
$call_cache = array();
while (list($i, $data) = each($this->fields)) {
switch ($data[0]) {
case "hidden":
$hidden[] = $i;
continue 2;
case "reset":
$params = 1;
break;
case "submit":
case "image":
$params = 2;
break;
case "checkbox":
$params = 3;
break;
case "text":
case "password":
case "radio":
$params = 4;
break;
case "textarea":
$params = 5;
break;
case "select":
$params = 7;
break;
default:
// unknown field type
continue 2;
}
$str = $call_cache[$params];
if (!$str) {
$str = '$this->display'.ucfirst($data[0])."Row(";
for ($i = 1; $i <= $params; $i++) {
$str .= '$data['.$i.']';
if ($i < $params) $str .= ', ';
}
$str .= ');';
$call_cache[$params] = $str;
}
eval($str);
}
print "</TABLE>\n";
for ($i = 0; $i < sizeof($hidden); $i++) {
$this->displayHidden($this->fields[$hidden[$i]][1],
$this->fields[$hidden[$i]][2]);
}
$this->end();
}
// }}}
}
?>
Index: pearweb/public_html/authors.php
+++ pearweb/public_html/authors.php
<?php
pageHeader("PEAR: Authors");
print "<H1>Authors</H1>\n";
$sth = $dbh->query('SELECT handle,name,email,homepage,showemail '.
'FROM authors WHERE registered = 1');
if (DB::isError($sth)) {
die("query failed: ".DB::errorMessage($dbh)."<BR>\n");
}
print "<TABLE BORDER=1>\n";
print " <TR>\n";
print " <TH>Handle</TH>\n";
print " <TH>Name</TH>\n";
print " <TH>Email</TH>\n";
print " <TH>Homepage</TH>\n";
print " </TR>\n";
while (is_array($row = $sth->fetchRow(DB_GETMODE_ASSOC))) {
extract($row);
print " <TR>\n";
print " <TD>$handle</TD>\n";
print " <TD>$name</TD>\n";
if ($showemail) {
print " <TD><A HREF=\"mailto:$email\">$email</A></TD>\n";
} else {
print " <TD>(not shown)</TD>\n";
}
print " <TD><A
HREF=\"$homepage\">$homepage</A></TD>\n";
print " </TR>\n";
}
print "</TABLE>\n";
pageFooter();
?>