4 * Class Generator for FusionForge
6 * Copyright 2005 (c) Francisco Gimeno
8 * This file is part of FusionForge. FusionForge is free software;
9 * you can redistribute it and/or modify it under the terms of the
10 * GNU General Public License as published by the Free Software
11 * Foundation; either version 2 of the Licence, or (at your option)
14 * FusionForge is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with FusionForge; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 require ('squal_pre.php');
26 function capitalize($name) {
27 $tmp = str_replace ("_", " ", $name );
28 $tmp2 = ucwords ($tmp);
29 return str_replace(" ","", $tmp2);
33 function generateHeader($tableName,$author="Gforge Class Generator by Francisco Gimeno", $project="Gforge" ) {
34 /* In the future, we should be able to read this from a file */
37 " * FusionForge %{CLASS_NAME} Facility\n".
39 " * Copyright (c) %{YEAR} %{AUTHOR}\n".
41 " * This file is part of FusionForge. FusionForge is free software;\n".
42 " * you can redistribute it and/or modify it under the terms of the\n".
43 " * GNU General Public License as published by the Free Software\n".
44 " * Foundation; either version 2 of the Licence, or (at your option)\n".
45 " * any later version.\n".
47 " * FusionForge is distributed in the hope that it will be useful,\n".
48 " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n".
49 " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n".
50 " * GNU General Public License for more details.\n".
52 " * You should have received a copy of the GNU General Public License along\n".
53 " * with FusionForge; if not, write to the Free Software Foundation, Inc.,\n".
54 " * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n".
59 " * By %{AUTHOR}, %{YEAR}\n".
60 " * Rewrite in OO and coding guidelines 12/2002 by Tim Perdue\n".
63 "require_once('common/include/FFError.class');\n";
64 "require_once('common/include/Validator.class');\n\n";
66 $variables = array("%{CLASS_NAME}","%{YEAR}","%{AUTHOR}",
67 "%{PROJECT}", "%{TITLE}" );
68 $substitutions = array($tableName, date("Y"), $author, $project, capitalize($tableName) );
69 $output = str_replace( $variables, $substitutions, $input );
73 function generate_GETOBJECT($tableName) {
74 $input= "function &%{NAME}_get_object($%{ID_FIELD},\$data=false) {\n".
75 "\tglobal $%{OBJECT};\n".
76 "\tif (!isset($%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"])) {\n".
77 "\t\tif (\$data) {\n".
78 "\t\t\t//the db result handle was passed in\n".
80 "\t\t\t\$res=db_query(\"SELECT * FROM %{TABLE_NAME}\n".
81 "\t\t\t\tWHERE %{ID_FIELD}='$%{ID_FIELD}'\");\n\n".
82 "\t\t\tif (db_numrows(\$res) <1 ) {\n".
83 "\t\t\t\t$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]=false;\n".
84 "\t\t\t\treturn false;\n".
86 "\t\t\t\$data =& db_fetch_array(\$res);\n\n".
88 "\t\t//\$ProjectGroup =& projectgroup_get_object(\$data[\"group_project_id\"]);\n".
89 "\t\t//$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]= new %{CLASS_NAME}(\$ProjectGroup,$%{ID_FIELD},\$data);\n".
90 "\t\t$%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"]= new %{CLASS_NAME}($%{ID_FIELD},\$data);\n\n".
92 "\treturn $%{OBJECT}[\"_\".$%{ID_FIELD}.\"_\"];\n}\n\n";
93 $variables = array("%{NAME}","%{OBJECT}","%{TABLE_NAME}", "%{ID_FIELD}", "%{CLASS_NAME}" );
94 $reducedName=strtolower($tableName);
95 $reducedName=str_replace ( "_", "", $reducedName );
96 $objName = strtoupper($reducedName)."_OBJ";
97 $substitutions = array($reducedName, $objName, $tableName, $tableName."_id", Capitalize($tableName));
98 $output = str_replace($variables, $substitutions, $input);
105 function getIdFieldFromFieldsArr($fields) {
106 $keys=array_keys($fields);
110 function generateClassHead($className) {
111 $output="class ".$className." extends FFError {\n\n";
116 function generateClassVars($className) {
118 "\t * Associative array of data from db.\n".
120 "\t * @var array \$data_array.\n".
122 "\tvar \$data_array;\n".
124 "\t * The ProjectGroup object.\n".
126 "\t * @var object \$ProjectGroup.\n".
128 "\t// var \$ProjectGroup;\n";
132 function generateClassConstructor($className, $fields) {
134 "\t * Constructor.\n".
136 "\t * (@param object The ProjectGroup object to which this object is associated.)\n".
137 "\t * @param int The id.\n".
138 "\t * @param array The associative array of data.\n".
139 "\t * @return boolean success.\n".
141 $output.="\tfunction ".$className."(/*&\$ProjectGroup,*/ \$".getIdFieldFromFieldsArr($fields)."=false, \$arr=false) {\n";
142 $output.="\t\tparent::__construct(); \n\n".
143 "\t\t/*if (!\$ProjectGroup || !is_object(\$ProjectGroup)) {\n".
144 "\t\t\t\$this->setError('$className:: No Valid ProjectGroup Object');\n".
145 "\t\t\t\treturn false;\n".
147 "\t\tif (\$ProjectGroup->isError()) {\n".
148 "\t\t\t\$this->setError('$className:: '.\$ProjectGroup->getErrorMessage());\n".
149 "\t\t\t\treturn false;\n".
151 "\t\t\$this->ProjectGroup =& \$ProjectGroup;*/\n";
152 $input="\t\tif ($%{ID_FIELD}) {\n".
153 "\t\t\tif (!\$arr || !is_array(\$arr)) {\n".
154 "\t\t\t\tif (!\$this->fetchData($%{ID_FIELD})) {\n".
155 "\t\t\t\t\treturn false;\n".
158 "\t\t\t\t\$this->data_array =& \$arr;\n".
160 "\t\t\t\t// Verify this message truly belongs to this ProjectGroup\n".
162 "\t\t\t\t/*if (\$this->data_array['%{ID_FIELD}'] != \$this->ProjectGroup->getID()) {\n".
163 "\t\t\t\t\t\$this->setError('Group_project_id in db result does not match ProjectG roup Object');\n".
164 "\t\t\t\t\t\treturn false;\n".
168 "\t\treturn true;\n";
169 $variables=array("%{ID_FIELD}","KKKK");
170 $substitutions=array(getIdFieldFromFieldsArr($fields),"FFFF");
172 $output.=str_replace($variables,$substitutions,$input);
177 function generateClassObjectCreator($tableName,$className,$fields) {
180 "\t * create - create a new ".$className." in the database.\n\t *\n";
181 foreach ($fields as $fieldName => $field ) {
182 $output.="\t *\t@param ".$field["type"]." ".$fieldName.".\n";
184 $output.="\t * @return boolean Success.\n\t */\n";
186 $output.="\tfunction create(";
188 $lineLength = strlen(" function create(");
189 foreach ($fields as $fieldName => $field) {
191 $output.=","; // First occurence hasn't a comma before
192 $lineLength += strlen($fieldName );
193 if ($lineLength >= 80 ) {
194 $output.="\n\t\t"; // New line at 80
197 $output.="\$".$fieldName;
201 $output.="\t\t\$v = new Validator();\n";
202 foreach ($fields as $fieldName => $field ) {
203 $output.="\t\t\$v->check(\$".$fieldName.", \"".$fieldName."\");\n";
205 $output.="\t\tif (!\$v->isClean()) {\n".
206 "\t\t\t\$this->setError(\$v->formErrorMsg(\"Must include \"));\n".
207 "\t\t\treturn false;\n".
211 $output.="\t\t/* CHECK FOR PERMISSION\n".
212 "\t\t\$perm =& \$this->ProjectGroup->Group->getPermission( session_get_user() );\n\n".
213 "\t\tif (!\$perm || !is_object(\$perm) || !\$perm->isXXAdmin()) {\n".
214 "\t\t\$this->setPermissionDeniedError();\n".
215 "\t\t\treturn false;\n".
218 /* Hard Work: SQL Sentence */
219 $input="\t\tdb_begin();\n\n".
220 "\t\t\$res=db_query(\"SELECT nextval('%{TABLE_NAME}_pk_seq') AS id\");\n".
221 "\t\tif (!$%{ID_FIELD}=db_result(\$res,0,'id')) {\n".
222 "\t\t\t\$this->setError('Could Not Get Next ID');\n".
223 "\t\t\tdb_rollback();\n".
224 "\t\t\treturn false;\n".
226 "\t\t\t\$this->data_array['%{ID_FIELD}']=$%{ID_FIELD};\n".
228 "\t\t\t/* SEVERAL CHECKS more\n".
229 "\t\t\tif (!\$this->setDependentOn(\$depend_arr)) {\n".
230 "\t\t\t\tdb_rollback();\n".
231 "\t\t\t\treturn false;\n".
232 "\t\t\t} elseif (!\$this->setAssignedTo(\$assigned_arr)) {\n".
233 "\t\t\t\tdb_rollback();\n".
234 "\t\t\t\treturn false;\n".
235 "\t\t\t} else { */\n".
236 "\t\t\t\t\$sql=\"INSERT INTO %{TABLE_NAME} (%{ALL_FIELDS})\n".
237 "\t\t\t\t\tVALUES (%{ALL_VALUES})\";\n";
241 /* Preparing SQL sentence */
242 foreach($fields as $fieldName => $field )
244 if ($count++ != 0 ) {
248 $field_len += strlen($fieldName);
249 if ($field_len > 80) {
250 $all_fields.="\n\t\t\t\t\t";
253 $all_fields.=$fieldName;
254 if ($field["type"] == "string" || $field["type"] == "bpchar" ) {
255 $values_len += strlen ("'\".htmlspecialchars(\$".$fieldName.").\"'");
256 if ($values_len > 80 ) {
257 $all_values.="\n\t\t\t\t\t";
260 $all_values.="'\".htmlspecialchars(\$".$fieldName.").\"'";
262 $values_len += strlen ("'\".\$".$fieldName.".\"'");
263 if ($values_len > 80 ) {
264 $all_values.="\n\t\t\t\t\t";
267 $all_values.="'\".\$".$fieldName.".\"'";
270 $variables = array ("%{TABLE_NAME}","%{ID_FIELD}","%{ALL_FIELDS}", "%{ALL_VALUES}","%{CLASSNAME}");
271 $substitutions = array ( $tableName, getIdFieldFromFieldsArr($fields), $all_fields, $all_values, $className );
272 $output.=str_replace($variables,$substitutions,$input);
274 $input="\t\t\t\t\$result=db_query(\$sql);\n".
275 "\t\t\t\tif (!\$result || db_affected_rows(\$result) < 1) {\n".
276 "\t\t\t\t\t\$this->setError('%{CLASSNAME}::create() Posting Failed '.db_error());\n".
277 "\t\t\t\t\tdb_rollback();\n".
278 "\t\t\t\t\treturn false;\n".
279 "\t\t\t\t} else {\n".
280 "\t\t\t\t\tif (!\$this->fetchData(\$%{ID_FIELD})) {\n".
281 "\t\t\t\t\t\tdb_rollback();\n".
282 "\t\t\t\t\t\treturn false;\n".
283 "\t\t\t\t\t} else {\n".
284 "\t\t\t\t\t\t/* \$this->sendNotice(1); */\n".
285 "\t\t\t\t\t\tdb_commit();\n".
286 "\t\t\t\t\t\treturn true;\n".
291 $output.=str_replace($variables,$substitutions,$input);
296 function generateClassFetchData($tableName,$className,$fields) {
298 "\t * fetchData - re-fetch the data for this %{CLASSNAME} from the database.\n".
300 "\t * @param int The %{ID_FIELD}.\n".
301 "\t * @return boolean success.\n".
303 "\tfunction fetchData(\$%{ID_FIELD}) {\n".
304 "\t \$res=db_query(\"SELECT * FROM %{TABLE_NAME}\n".
305 "\t WHERE %{ID_FIELD}='$%{ID_FIELD}'\");\n".
306 "\t // AND group_project_id='\". \$this->ProjectGroup->getID() .\"'\");\n".
307 "\t if (!\$res || db_numrows(\$res) < 1) {\n".
308 "\t \$this->setError('%{CLASSNAME}::fetchData() Invalid ID'.db_error());\n".
309 "\t return false;\n".
311 "\t \$this->data_array =& db_fetch_array(\$res);\n".
312 "\t db_free_result(\$res);\n".
316 $variables= array("%{CLASSNAME}","%{ID_FIELD}","%{TABLE_NAME}");
317 $substitutions=array($className, getIdFieldFromFieldsArr($fields), $tableName );
318 $output= str_replace($variables, $substitutions, $input );
322 function generateClassGetID($className, $fields) {
324 "\t * getID - get this ".$className." ID\n".
326 "\t * @return int The ".getIdFieldFromFieldsArr($fields).".\n".
328 "\tfunction getID() {\n".
329 "\t\treturn \$this->data_array['".getIdFieldFromFieldsArr($fields)."'];\n".
335 function generateClassGetField($className,$fieldName,$field) {
337 "\t * %{FUNCTION_NAME} - get the field %{FIELD}.\n".
339 "\t * @return %{TYPE} The field.\n".
341 "\tfunction %{FUNCTION_NAME}() {\n".
342 "\t\treturn \$this->data_array['%{FIELD}'];\n".
344 $functionName="get". capitalize($fieldName);
345 $type="string"; // TO DO: Check the Field
346 $variables = array("%{FUNCTION_NAME}","%{FIELD}","%{TYPE}");
347 $substitutions= array($functionName, $fieldName, $field["type"] );
348 $output = str_replace($variables, $substitutions, $input );
353 function generateClassUpdate($tableName,$className,$fields) {
356 "\t * update - update a ".$className." in the database.\n\t *\n";
357 foreach ($fields as $fieldName => $field ) {
358 $output.="\t *\t@param ".$field["type"]." ".$fieldName.".\n";
360 $output.="\t * @return boolean Success.\n\t */\n";
362 $output.="\tfunction update(";
364 $lineLength = strlen(" function update(");
365 foreach ($fields as $fieldName => $field) {
367 $output.=","; // First occurence hasn't a comma before
368 $lineLength += strlen($fieldName );
369 if ($lineLength >= 80 ) {
370 $output.="\n\t\t"; // New line at 80
373 $output.="\$".$fieldName;
377 $output.="\t\t\$v = new Validator();\n";
378 foreach ($fields as $fieldName => $field ) {
379 $output.="\t\t\$v->check(\$".$fieldName.", \"".$fieldName."\");\n";
381 $output.="\t\tif (!\$v->isClean()) {\n".
382 "\t\t\t\$this->setError(\$v->formErrorMsg(\"Must include \"));\n".
383 "\t\t\treturn false;\n".
388 "\t\t// CHECK FOR PERMISSION\n".
389 "\t\t\$perm =& \$this->ProjectGroup->Group->getPermission( session_get_user() );\n\n".
390 "\t\tif (!\$perm || !is_object(\$perm)) {\n".
391 "\t\t} elseif (\$perm->isError()) {\n".
392 "\t\t\t\$this->setPermissionDeniedError();\n".
393 "\t\t\treturn false;\n".
394 "\t\t} elseif (!\$perm->isXXXAdmin()) {\n".
395 "\t\t\t\$this->setPermissionDeniedError();\n".
396 "\t\t\treturn false;\n".
399 /* Hard Work: SQL Sentence */
400 $output.="\t\tdb_begin();\n\n";
403 $output.="\t\t/* Several Checks */\n";
404 $output.="\t\t/* You _SHOULD_ check compulsory fields here */\n";
406 $output.="\t\t\$sql=\"UPDATE ".$tableName." SET \n\t\t\t";
408 foreach($fields as $fieldName => $field ) {
412 if ($field["type"]=="string" || $field["type"] =="bpchar") {
413 $output.="\t\t\t".$fieldName."='\".";
414 $output.="htmlspecialchars(\$".$fieldName.").\"'";
416 $output.="\t\t\t".$fieldName."='";
417 $output.="\$".$fieldName."'";
420 $output .= "\n\t\t\tWHERE ".getIdFieldFromFieldsArr($fields)."='\".\$this->getID().\"'\";\n";
421 $output .= "\t\t\t// WHERE group_project_id='$group_project_id'\n".
422 "\t\t\t// AND ".getIdFieldFromFieldsArr($fields)."='\".\$this->getID().\"'\";\n";
424 $output .= "\t\t\$res=db_query(\$sql);\n".
425 "\t\tif (!\$res || db_affected_rows(\$res) < 1) {\n".
426 "\t\t\t\$this->setError(_('Error On Update')._(': ').db_error());\n".
427 "\t\t\tdb_rollback();\n".
428 "\t\t\treturn false;\n".
430 "\t\t\tif (!$this->fetchData(\$this->getID())) {\n".
431 "\t\t\t\t\$this->setError(_('Error On Update')._(': ').db_error());\n".
432 "\t\t\t\tdb_rollback();\n".
433 "\t\t\t\treturn false;\n".
435 "\t\t\t\t/* \$this->sendNotice(); */\n".
436 "\t\t\t\tdb_commit();\n".
437 "\t\t\t\treturn true;\n".
445 function generateClassDelete($tableName, $fields) {
448 * delete() - delete this row from the database.
450 * @param boolean I\'m Sure.
451 * @return boolean true/false.
453 function delete($sure) {
455 $this->setError(\'Must be sure before deleting\');
458 $perm =& $this->Group->getPermission( session_get_user() );
459 if (!$perm || !is_object($perm)) {
460 $this->setPermissionDeniedError();
462 } elseif ($perm->isError()) {
463 $this->setPermissionDeniedError();
465 } elseif (!$perm->isAdmin()) {
466 $this->setPermissionDeniedError();
469 $res=db_query("DELETE FROM '.$tableName.' WHERE
470 '.getIdFieldFromFieldsArr($fields).'=\'".$this->getID()."\'");
471 if (!$res || db_affected_rows($res) < 1) {
472 $this->setError(\'Could Not Delete: \'.db_error());
481 function generateClassBottom($className) {
485 function generateClass($tableName, $fields ) {
486 $className = capitalize($tableName);
487 $output=generateClassHead($className); // Done
488 $output.=generateClassVars($className); // Done
489 $output.=generateClassConstructor($className,$fields); // Done
490 $output.=generateClassObjectCreator($tableName,$className,$fields); // Done
491 $output.=generateClassFetchData($tableName, $className,$fields); // Done
492 $output.=generateClassGetID($className,$fields); // DONE
493 foreach($fields as $fieldName => $field) {
494 $output.=generateClassGetField($className,$fieldName,$field); // Done
496 $output.=generateClassDelete($tableName,$fields);
497 $output.=generateClassUpdate($tableName, $className,$fields); // Done
498 $output.=generateClassBottom($className); // Done
506 print "Usage: ".$argv[0]." <table_name>\n";
512 $meta = pg_meta_data($conn, $tableName);
514 if ( ! is_array($meta) ) {
515 print "Error: table $tableName not found\n";
518 print generateHeader($tableName );
519 print generate_GETOBJECT($tableName );
520 print generateClass($tableName, $meta );