4 * Class Generator for Gforge
6 * Copyright 2005 (c) Francisco Gimeno
8 * This file is part of FusionForge.
10 * FusionForge is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * FusionForge is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with FusionForge; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US
25 require ('squal_pre.php');
27 function capitalize($name) {
28 $tmp = str_replace ("_", " ", $name );
29 $tmp2 = ucwords ($tmp);
30 return str_replace(" ","", $tmp2);
34 function generateHeader($tableName,$author="Gforge Class Generator by Francisco Gimeno", $project="Gforge" ) {
35 /* In the future, we should be able to read this from a file */
38 " * Gforge %{CLASS_NAME} Facility\n".
40 " * Copyright %{YEAR} (c) %{AUTHOR}\n".
42 " * This file is part of %{PROJECT}.\n".
45 " * %{PROJECT} is free software: you can redistribute it and/or modify\n".
46 " * it under the terms of the GNU General Public License as published by\n".
47 " * the Free Software Foundation; either version 2 of the License, or\n".
48 " * (at your option) any later version.\n".
50 " * %{PROJECT} distributed in the hope that it will be useful,\n".
51 " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n".
52 " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n".
53 " * GNU General Public License for more details.\n".
55 " * You should have received a copy of the GNU General Public License\n".
56 " * along with %{PROJECT}; if not, write to the Free Software\n".
57 " * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 US\n".
59 "/*\n\n\n\t%{TITLE}\n\tBy %{AUTHOR}, %{YEAR}\n\n\tRewrite in OO and coding ".
60 "guidelines 12/2002 by Tim Perdue\n\n\n*/\n".
61 "require_once('common/include/Error.class');\n";
62 "require_once('common/include/Validator.class');\n\n";
64 $variables = array("%{CLASS_NAME}","%{YEAR}","%{AUTHOR}",
65 "%{PROJECT}", "%{TITLE}" );
66 $substitutions = array($tableName, date("Y"), $author, $project, capitalize($tableName) );
67 $output = str_replace( $variables, $substitutions, $input );
71 function generate_GETOBJECT($tableName) {
72 $input= "function &%{NAME}_get_object($%{ID_FIELD},\$data=false) {\n".
73 "\tglobal $%{OBJECT};\n".
74 "\tif (!isset($%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"])) {\n".
75 "\t\tif (\$data) {\n".
76 "\t\t\t//the db result handle was passed in\n".
78 "\t\t\t\$res=db_query(\"SELECT * FROM %{TABLE_NAME}\n".
79 "\t\t\t\tWHERE %{ID_FIELD}='$%{ID_FIELD}'\");\n\n".
80 "\t\t\tif (db_numrows(\$res) <1 ) {\n".
81 "\t\t\t\t$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]=false;\n".
82 "\t\t\t\treturn false;\n".
84 "\t\t\t\$data =& db_fetch_array(\$res);\n\n".
86 "\t\t//\$ProjectGroup =& projectgroup_get_object(\$data[\"group_project_id\"]);\n".
87 "\t\t//$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]= new %{CLASS_NAME}(\$ProjectGroup,$%{ID_FIELD},\$data);\n".
88 "\t\t$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]= new %{CLASS_NAME}($%{ID_FIELD},\$data);\n\n".
90 "\treturn $%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"];\n}\n\n";
91 $variables = array("%{NAME}","%{OBJECT}","%{TABLE_NAME}", "%{ID_FIELD}", "%{CLASS_NAME}" );
92 $reducedName=strtolower($tableName);
93 $reducedName=str_replace ( "_", "", $reducedName );
94 $objName = strtoupper($reducedName)."_OBJ";
95 $substitutions = array($reducedName, $objName, $tableName, $tableName."_id", Capitalize($tableName));
96 $output = str_replace($variables, $substitutions, $input);
103 function getIdFieldFromFieldsArr($fields) {
104 $keys=array_keys($fields);
108 function generateClassHead($className) {
109 $output="class ".$className." extends Error {\n\n";
114 function generateClassVars($className) {
116 "\t * Associative array of data from db.\n".
118 "\t * @var array \$data_array.\n".
120 "\tvar \$data_array;\n".
122 "\t * The ProjectGroup object.\n".
124 "\t * @var object \$ProjectGroup.\n".
126 "\t// var \$ProjectGroup;\n";
130 function generateClassConstructor($className, $fields) {
132 "\t * Constructor.\n".
134 "\t * (@param object The ProjectGroup object to which this object is associated.)\n".
135 "\t * @param int The id.\n".
136 "\t * @param array The associative array of data.\n".
137 "\t * @return boolean success.\n".
139 $output.="\tfunction ".$className."(/*&\$ProjectGroup,*/ \$".getIdFieldFromFieldsArr($fields)."=false, \$arr=false) {\n";
140 $output.="\t\t\$this->error(); \n\n".
141 "\t\t/*if (!\$ProjectGroup || !is_object(\$ProjectGroup)) {\n".
142 "\t\t\t\$this->setError('$className:: No Valid ProjectGroup Object');\n".
143 "\t\t\t\treturn false;\n".
145 "\t\tif (\$ProjectGroup->isError()) {\n".
146 "\t\t\t\$this->setError('$className:: '.\$ProjectGroup->getErrorMessage());\n".
147 "\t\t\t\treturn false;\n".
149 "\t\t\$this->ProjectGroup =& \$ProjectGroup;*/\n";
150 $input="\t\tif ($%{ID_FIELD}) {\n".
151 "\t\t\tif (!\$arr || !is_array(\$arr)) {\n".
152 "\t\t\t\tif (!\$this->fetchData($%{ID_FIELD})) {\n".
153 "\t\t\t\t\treturn false;\n".
156 "\t\t\t\t\$this->data_array =& \$arr;\n".
158 "\t\t\t\t// Verify this message truly belongs to this ProjectGroup\n".
160 "\t\t\t\t/*if (\$this->data_array['%{ID_FIELD}'] != \$this->ProjectGroup->getID()) {\n".
161 "\t\t\t\t\t\$this->setError('Group_project_id in db result does not match ProjectG roup Object');\n".
162 "\t\t\t\t\t\treturn false;\n".
166 "\t\treturn true;\n";
167 $variables=array("%{ID_FIELD}","KKKK");
168 $substitutions=array(getIdFieldFromFieldsArr($fields),"FFFF");
170 $output.=str_replace($variables,$substitutions,$input);
175 function generateClassObjectCreator($tableName,$className,$fields) {
178 "\t * create - create a new ".$className." in the database.\n\t *\n";
179 foreach ($fields as $fieldName => $field ) {
180 $output.="\t *\t@param ".$field["type"]." ".$fieldName.".\n";
182 $output.="\t * @return boolean Success.\n\t */\n";
184 $output.="\tfunction create(";
186 $lineLength = strlen(" function create(");
187 foreach ($fields as $fieldName => $field) {
189 $output.=","; // First occurence hasn't a comma before
190 $lineLength += strlen($fieldName );
191 if ($lineLength >= 80 ) {
192 $output.="\n\t\t"; // New line at 80
195 $output.="\$".$fieldName;
199 $output.="\t\t\$v = new Validator();\n";
200 foreach ($fields as $fieldName => $field ) {
201 $output.="\t\t\$v->check(\$".$fieldName.", \"".$fieldName."\");\n";
203 $output.="\t\tif (!\$v->isClean()) {\n".
204 "\t\t\t\$this->setError(\$v->formErrorMsg(\"Must include \"));\n".
205 "\t\t\treturn false;\n".
209 $output.="\t\t/* CHECK FOR PERMISSION\n".
210 "\t\t\$perm =& \$this->ProjectGroup->Group->getPermission( session_get_user() );\n\n".
211 "\t\tif (!\$perm || !is_object(\$perm) || !\$perm->isXXAdmin()) {\n".
212 "\t\t\$this->setPermissionDeniedError();\n".
213 "\t\t\treturn false;\n".
216 /* Hard Work: SQL Sentence */
217 $input="\t\tdb_begin();\n\n".
218 "\t\t\$res=db_query(\"SELECT nextval('%{TABLE_NAME}_pk_seq') AS id\");\n".
219 "\t\tif (!$%{ID_FIELD}=db_result(\$res,0,'id')) {\n".
220 "\t\t\t\$this->setError('Could Not Get Next ID');\n".
221 "\t\t\tdb_rollback();\n".
222 "\t\t\treturn false;\n".
224 "\t\t\t\$this->data_array['%{ID_FIELD}']=$%{ID_FIELD};\n".
226 "\t\t\t/* SEVERAL CHECKS more\n".
227 "\t\t\tif (!\$this->setDependentOn(\$depend_arr)) {\n".
228 "\t\t\t\tdb_rollback();\n".
229 "\t\t\t\treturn false;\n".
230 "\t\t\t} elseif (!\$this->setAssignedTo(\$assigned_arr)) {\n".
231 "\t\t\t\tdb_rollback();\n".
232 "\t\t\t\treturn false;\n".
233 "\t\t\t} else { */\n".
234 "\t\t\t\t\$sql=\"INSERT INTO %{TABLE_NAME} (%{ALL_FIELDS})\n".
235 "\t\t\t\t\tVALUES (%{ALL_VALUES})\";\n";
239 /* Preparing SQL sentence */
240 foreach($fields as $fieldName => $field )
242 if ($count++ != 0 ) {
246 $field_len += strlen($fieldName);
247 if ($field_len > 80) {
248 $all_fields.="\n\t\t\t\t\t";
251 $all_fields.=$fieldName;
252 if ($field["type"] == "string" || $field["type"] == "bpchar" ) {
253 $values_len += strlen ("'\".htmlspecialchars(\$".$fieldName.").\"'");
254 if ($values_len > 80 ) {
255 $all_values.="\n\t\t\t\t\t";
258 $all_values.="'\".htmlspecialchars(\$".$fieldName.").\"'";
260 $values_len += strlen ("'\".\$".$fieldName.".\"'");
261 if ($values_len > 80 ) {
262 $all_values.="\n\t\t\t\t\t";
265 $all_values.="'\".\$".$fieldName.".\"'";
268 $variables = array ("%{TABLE_NAME}","%{ID_FIELD}","%{ALL_FIELDS}", "%{ALL_VALUES}","%{CLASSNAME}");
269 $substitutions = array ( $tableName, getIdFieldFromFieldsArr($fields), $all_fields, $all_values, $className );
270 $output.=str_replace($variables,$substitutions,$input);
272 $input="\t\t\t\t\$result=db_query(\$sql);\n".
273 "\t\t\t\tif (!\$result || db_affected_rows(\$result) < 1) {\n".
274 "\t\t\t\t\t\$this->setError('%{CLASSNAME}::create() Posting Failed '.db_error());\n".
275 "\t\t\t\t\tdb_rollback();\n".
276 "\t\t\t\t\treturn false;\n".
277 "\t\t\t\t} else {\n".
278 "\t\t\t\t\tif (!\$this->fetchData(\$%{ID_FIELD})) {\n".
279 "\t\t\t\t\t\tdb_rollback();\n".
280 "\t\t\t\t\t\treturn false;\n".
281 "\t\t\t\t\t} else {\n".
282 "\t\t\t\t\t\t/* \$this->sendNotice(1); */\n".
283 "\t\t\t\t\t\tdb_commit();\n".
284 "\t\t\t\t\t\treturn true;\n".
289 $output.=str_replace($variables,$substitutions,$input);
294 function generateClassFetchData($tableName,$className,$fields) {
296 "\t * fetchData - re-fetch the data for this %{CLASSNAME} from the database.\n".
298 "\t * @param int The %{ID_FIELD}.\n".
299 "\t * @return boolean success.\n".
301 "\tfunction fetchData(\$%{ID_FIELD}) {\n".
302 "\t \$res=db_query(\"SELECT * FROM %{TABLE_NAME}\n".
303 "\t WHERE %{ID_FIELD}='$%{ID_FIELD}'\");\n".
304 "\t // AND group_project_id='\". \$this->ProjectGroup->getID() .\"'\");\n".
305 "\t if (!\$res || db_numrows(\$res) < 1) {\n".
306 "\t \$this->setError('%{CLASSNAME}::fetchData() Invalid ID'.db_error());\n".
307 "\t return false;\n".
309 "\t \$this->data_array =& db_fetch_array(\$res);\n".
310 "\t db_free_result(\$res);\n".
314 $variables= array("%{CLASSNAME}","%{ID_FIELD}","%{TABLE_NAME}");
315 $substitutions=array($className, getIdFieldFromFieldsArr($fields), $tableName );
316 $output= str_replace($variables, $substitutions, $input );
320 function generateClassGetID($className, $fields) {
322 "\t * getID - get this ".$className." ID\n".
324 "\t * @return int The ".getIdFieldFromFieldsArr($fields).".\n".
326 "\tfunction getID() {\n".
327 "\t\treturn \$this->data_array['".getIdFieldFromFieldsArr($fields)."'];\n".
333 function generateClassGetField($className,$fieldName,$field) {
335 "\t * %{FUNCTION_NAME} - get the field %{FIELD}.\n".
337 "\t * @return %{TYPE} The field.\n".
339 "\tfunction %{FUNCTION_NAME}() {\n".
340 "\t\treturn \$this->data_array['%{FIELD}'];\n".
342 $functionName="get". capitalize($fieldName);
343 $type="string"; // TO DO: Check the Field
344 $variables = array("%{FUNCTION_NAME}","%{FIELD}","%{TYPE}");
345 $substitutions= array($functionName, $fieldName, $field["type"] );
346 $output = str_replace($variables, $substitutions, $input );
351 function generateClassUpdate($tableName,$className,$fields) {
354 "\t * update - update a ".$className." in the database.\n\t *\n";
355 foreach ($fields as $fieldName => $field ) {
356 $output.="\t *\t@param ".$field["type"]." ".$fieldName.".\n";
358 $output.="\t * @return boolean Success.\n\t */\n";
360 $output.="\tfunction update(";
362 $lineLength = strlen(" function update(");
363 foreach ($fields as $fieldName => $field) {
365 $output.=","; // First occurence hasn't a comma before
366 $lineLength += strlen($fieldName );
367 if ($lineLength >= 80 ) {
368 $output.="\n\t\t"; // New line at 80
371 $output.="\$".$fieldName;
375 $output.="\t\t\$v = new Validator();\n";
376 foreach ($fields as $fieldName => $field ) {
377 $output.="\t\t\$v->check(\$".$fieldName.", \"".$fieldName."\");\n";
379 $output.="\t\tif (!\$v->isClean()) {\n".
380 "\t\t\t\$this->setError(\$v->formErrorMsg(\"Must include \"));\n".
381 "\t\t\treturn false;\n".
386 "\t\t// CHECK FOR PERMISSION\n".
387 "\t\t\$perm =& \$this->ProjectGroup->Group->getPermission( session_get_user() );\n\n".
388 "\t\tif (!\$perm || !is_object(\$perm)) {\n".
389 "\t\t} elseif (\$perm->isError()) {\n".
390 "\t\t\t\$this->setPermissionDeniedError();\n".
391 "\t\t\treturn false;\n".
392 "\t\t} elseif (!\$perm->isXXXAdmin()) {\n".
393 "\t\t\t\$this->setPermissionDeniedError();\n".
394 "\t\t\treturn false;\n".
397 /* Hard Work: SQL Sentence */
398 $output.="\t\tdb_begin();\n\n";
401 $output.="\t\t/* Several Checks */\n";
402 $output.="\t\t/* You _SHOULD_ check compulsory fields here */\n";
404 $output.="\t\t\$sql=\"UPDATE ".$tableName." SET \n\t\t\t";
406 foreach($fields as $fieldName => $field ) {
410 if ($field["type"]=="string" || $field["type"] =="bpchar") {
411 $output.="\t\t\t".$fieldName."='\".";
412 $output.="htmlspecialchars(\$".$fieldName.").\"'";
414 $output.="\t\t\t".$fieldName."='";
415 $output.="\$".$fieldName."'";
418 $output .= "\n\t\t\tWHERE ".getIdFieldFromFieldsArr($fields)."='\".\$this->getID().\"'\";\n";
419 $output .= "\t\t\t// WHERE group_project_id='$group_project_id'\n".
420 "\t\t\t// AND ".getIdFieldFromFieldsArr($fields)."='\".\$this->getID().\"'\";\n";
422 $output .= "\t\t\$res=db_query(\$sql);\n".
423 "\t\tif (!\$res || db_affected_rows(\$res) < 1) {\n".
424 "\t\t\t\$this->setError('Error On Update: '.db_error());\n".
425 "\t\t\tdb_rollback();\n".
426 "\t\t\treturn false;\n".
428 "\t\t\tif (!$this->fetchData(\$this->getID())) {\n".
429 "\t\t\t\t\$this->setError('Error On Update: '.db_error());\n".
430 "\t\t\t\tdb_rollback();\n".
431 "\t\t\t\treturn false;\n".
433 "\t\t\t\t/* \$this->sendNotice(); */\n".
434 "\t\t\t\tdb_commit();\n".
435 "\t\t\t\treturn true;\n".
443 function generateClassDelete($tableName, $fields) {
446 * delete() - delete this row from the database.
448 * @param boolean I\'m Sure.
449 * @return boolean true/false.
451 function delete($sure) {
453 $this->setError(\'Must be sure before deleting\');
456 $perm =& $this->Group->getPermission( session_get_user() );
457 if (!$perm || !is_object($perm)) {
458 $this->setPermissionDeniedError();
460 } elseif ($perm->isError()) {
461 $this->setPermissionDeniedError();
463 } elseif (!$perm->isAdmin()) {
464 $this->setPermissionDeniedError();
467 $res=db_query("DELETE FROM '.$tableName.' WHERE
468 '.getIdFieldFromFieldsArr($fields).'=\'".$this->getID()."\'");
469 if (!$res || db_affected_rows($res) < 1) {
470 $this->setError(\'Could Not Delete: \'.db_error());
479 function generateClassBottom($className) {
483 function generateClass($tableName, $fields ) {
484 $className = capitalize($tableName);
485 $output=generateClassHead($className); // Done
486 $output.=generateClassVars($className); // Done
487 $output.=generateClassConstructor($className,$fields); // Done
488 $output.=generateClassObjectCreator($tableName,$className,$fields); // Done
489 $output.=generateClassFetchData($tableName, $className,$fields); // Done
490 $output.=generateClassGetID($className,$fields); // DONE
491 foreach($fields as $fieldName => $field) {
492 $output.=generateClassGetField($className,$fieldName,$field); // Done
494 $output.=generateClassDelete($tableName,$fields);
495 $output.=generateClassUpdate($tableName, $className,$fields); // Done
496 $output.=generateClassBottom($className); // Done
504 print "Usage: ".$argv[0]." <table_name>\n";
510 $meta = pg_meta_data($conn, $tableName);
512 if ( ! is_array($meta) ) {
513 print "Error: table $tableName not found\n";
516 print generateHeader($tableName );
517 print generate_GETOBJECT($tableName );
518 print generateClass($tableName, $meta );