[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /*+******************************************************************************** 3 * The contents of this file are subject to the vtiger CRM Public License Version 1.0 4 * ("License"); You may not use this file except in compliance with the License 5 * The Original Code is: vtiger CRM Open Source 6 * The Initial Developer of the Original Code is vtiger. 7 * Portions created by vtiger are Copyright (C) vtiger. 8 * All Rights Reserved. 9 ********************************************************************************/ 10 11 // Note is used to store customer information. 12 class Documents extends CRMEntity { 13 14 var $log; 15 var $db; 16 var $table_name = "vtiger_notes"; 17 var $table_index= 'notesid'; 18 var $default_note_name_dom = array('Meeting vtiger_notes', 'Reminder'); 19 20 var $tab_name = Array('vtiger_crmentity','vtiger_notes','vtiger_notescf'); 21 var $tab_name_index = Array('vtiger_crmentity'=>'crmid','vtiger_notes'=>'notesid','vtiger_senotesrel'=>'notesid','vtiger_notescf'=>'notesid'); 22 23 /** 24 * Mandatory table for supporting custom fields. 25 */ 26 var $customFieldTable = Array('vtiger_notescf', 'notesid'); 27 28 var $column_fields = Array(); 29 30 var $sortby_fields = Array('title','modifiedtime','filename','createdtime','lastname','filedownloadcount','smownerid'); 31 32 // This is used to retrieve related vtiger_fields from form posts. 33 var $additional_column_fields = Array('', '', '', ''); 34 35 // This is the list of vtiger_fields that are in the lists. 36 var $list_fields = Array( 37 'Title'=>Array('notes'=>'title'), 38 'File Name'=>Array('notes'=>'filename'), 39 'Modified Time'=>Array('crmentity'=>'modifiedtime'), 40 'Assigned To' => Array('crmentity'=>'smownerid'), 41 'Folder Name' => Array('attachmentsfolder'=>'folderid') 42 ); 43 var $list_fields_name = Array( 44 'Title'=>'notes_title', 45 'File Name'=>'filename', 46 'Modified Time'=>'modifiedtime', 47 'Assigned To'=>'assigned_user_id', 48 'Folder Name' => 'folderid' 49 ); 50 51 var $search_fields = Array( 52 'Title' => Array('notes'=>'notes_title'), 53 'File Name' => Array('notes'=>'filename'), 54 'Assigned To' => Array('crmentity'=>'smownerid'), 55 'Folder Name' => Array('attachmentsfolder'=>'foldername') 56 ); 57 58 var $search_fields_name = Array( 59 'Title' => 'notes_title', 60 'File Name' => 'filename', 61 'Assigned To' => 'assigned_user_id', 62 'Folder Name' => 'folderid' 63 ); 64 var $list_link_field= 'notes_title'; 65 var $old_filename = ''; 66 //var $groupTable = Array('vtiger_notegrouprelation','notesid'); 67 68 var $mandatory_fields = Array('notes_title','createdtime' ,'modifiedtime','filename','filesize','filetype','filedownloadcount','assigned_user_id'); 69 70 //Added these variables which are used as default order by and sortorder in ListView 71 var $default_order_by = 'title'; 72 var $default_sort_order = 'ASC'; 73 function Documents() { 74 $this->log = LoggerManager::getLogger('notes'); 75 $this->log->debug("Entering Documents() method ..."); 76 $this->db = PearDatabase::getInstance(); 77 $this->column_fields = getColumnFields('Documents'); 78 $this->log->debug("Exiting Documents method ..."); 79 } 80 81 function save_module($module) 82 { 83 global $log,$adb,$upload_badext; 84 $insertion_mode = $this->mode; 85 if(isset($this->parentid) && $this->parentid != '') 86 $relid = $this->parentid; 87 //inserting into vtiger_senotesrel 88 if(isset($relid) && $relid != '') 89 { 90 $this->insertintonotesrel($relid,$this->id); 91 } 92 $filetype_fieldname = $this->getFileTypeFieldName(); 93 $filename_fieldname = $this->getFile_FieldName(); 94 if($this->column_fields[$filetype_fieldname] == 'I' ){ 95 if($_FILES[$filename_fieldname]['name'] != ''){ 96 $errCode=$_FILES[$filename_fieldname]['error']; 97 if($errCode == 0){ 98 foreach($_FILES as $fileindex => $files) 99 { 100 if($files['name'] != '' && $files['size'] > 0){ 101 $filename = $_FILES[$filename_fieldname]['name']; 102 $filename = from_html(preg_replace('/\s+/', '_', $filename)); 103 $filetype = $_FILES[$filename_fieldname]['type']; 104 $filesize = $_FILES[$filename_fieldname]['size']; 105 $filelocationtype = 'I'; 106 $binFile = sanitizeUploadFileName($filename, $upload_badext); 107 $filename = ltrim(basename(" ".$binFile)); //allowed filename like UTF-8 characters 108 } 109 } 110 111 } 112 }elseif($this->mode == 'edit') { 113 $fileres = $adb->pquery("select filetype, filesize,filename,filedownloadcount,filelocationtype from vtiger_notes where notesid=?", array($this->id)); 114 if ($adb->num_rows($fileres) > 0) { 115 $filename = $adb->query_result($fileres, 0, 'filename'); 116 $filetype = $adb->query_result($fileres, 0, 'filetype'); 117 $filesize = $adb->query_result($fileres, 0, 'filesize'); 118 $filedownloadcount = $adb->query_result($fileres, 0, 'filedownloadcount'); 119 $filelocationtype = $adb->query_result($fileres, 0, 'filelocationtype'); 120 } 121 }elseif($this->column_fields[$filename_fieldname]) { 122 $filename = $this->column_fields[$filename_fieldname]; 123 $filesize = $this->column_fields['filesize']; 124 $filetype = $this->column_fields['filetype']; 125 $filelocationtype = $this->column_fields[$filetype_fieldname]; 126 $filedownloadcount = 0; 127 } else { 128 $filelocationtype = 'I'; 129 $filetype = ''; 130 $filesize = 0; 131 $filedownloadcount = null; 132 } 133 } else if($this->column_fields[$filetype_fieldname] == 'E' ){ 134 $filelocationtype = 'E'; 135 $filename = $this->column_fields[$filename_fieldname]; 136 // If filename does not has the protocol prefix, default it to http:// 137 // Protocol prefix could be like (https://, smb://, file://, \\, smb:\\,...) 138 if(!empty($filename) && !preg_match('/^\w{1,5}:\/\/|^\w{0,3}:?\\\\\\\\/', trim($filename), $match)) { 139 $filename = "http://$filename"; 140 } 141 $filetype = ''; 142 $filesize = 0; 143 $filedownloadcount = null; 144 } 145 $query = "UPDATE vtiger_notes SET filename = ? ,filesize = ?, filetype = ? , filelocationtype = ? , filedownloadcount = ? WHERE notesid = ?"; 146 $re=$adb->pquery($query,array(decode_html($filename),$filesize,$filetype,$filelocationtype,$filedownloadcount,$this->id)); 147 //Inserting into attachments table 148 if($filelocationtype == 'I') { 149 $this->insertIntoAttachment($this->id,'Documents'); 150 }else{ 151 $query = "delete from vtiger_seattachmentsrel where crmid = ?"; 152 $qparams = array($this->id); 153 $adb->pquery($query, $qparams); 154 } 155 //set the column_fields so that its available in the event handlers 156 $this->column_fields['filename'] = $filename; 157 $this->column_fields['filesize'] = $filesize; 158 $this->column_fields['filetype'] = $filetype; 159 $this->column_fields['filedownloadcount'] = $filedownloadcount; 160 } 161 162 163 /** 164 * This function is used to add the vtiger_attachments. This will call the function uploadAndSaveFile which will upload the attachment into the server and save that attachment information in the database. 165 * @param int $id - entity id to which the vtiger_files to be uploaded 166 * @param string $module - the current module name 167 */ 168 function insertIntoAttachment($id,$module) 169 { 170 global $log, $adb; 171 $log->debug("Entering into insertIntoAttachment($id,$module) method."); 172 173 $file_saved = false; 174 175 foreach($_FILES as $fileindex => $files) 176 { 177 if($files['name'] != '' && $files['size'] > 0) 178 { 179 $files['original_name'] = vtlib_purify($_REQUEST[$fileindex.'_hidden']); 180 $file_saved = $this->uploadAndSaveFile($id,$module,$files); 181 } 182 } 183 184 $log->debug("Exiting from insertIntoAttachment($id,$module) method."); 185 } 186 187 /** Function used to get the sort order for Documents listview 188 * @return string $sorder - first check the $_REQUEST['sorder'] if request value is empty then check in the $_SESSION['NOTES_SORT_ORDER'] if this session value is empty then default sort order will be returned. 189 */ 190 function getSortOrder() 191 { 192 global $log; 193 $log->debug("Entering getSortOrder() method ..."); 194 if(isset($_REQUEST['sorder'])) 195 $sorder = $this->db->sql_escape_string($_REQUEST['sorder']); 196 else 197 $sorder = (($_SESSION['NOTES_SORT_ORDER'] != '')?($_SESSION['NOTES_SORT_ORDER']):($this->default_sort_order)); 198 $log->debug("Exiting getSortOrder() method ..."); 199 return $sorder; 200 } 201 202 /** Function used to get the order by value for Documents listview 203 * @return string $order_by - first check the $_REQUEST['order_by'] if request value is empty then check in the $_SESSION['NOTES_ORDER_BY'] if this session value is empty then default order by will be returned. 204 */ 205 function getOrderBy() 206 { 207 global $log; 208 $log->debug("Entering getOrderBy() method ..."); 209 210 $use_default_order_by = ''; 211 if(PerformancePrefs::getBoolean('LISTVIEW_DEFAULT_SORTING', true)) { 212 $use_default_order_by = $this->default_order_by; 213 } 214 215 if (isset($_REQUEST['order_by'])) 216 $order_by = $this->db->sql_escape_string($_REQUEST['order_by']); 217 else 218 $order_by = (($_SESSION['NOTES_ORDER_BY'] != '')?($_SESSION['NOTES_ORDER_BY']):($use_default_order_by)); 219 $log->debug("Exiting getOrderBy method ..."); 220 return $order_by; 221 } 222 223 /** 224 * Function used to get the sort order for Documents listview 225 * @return String $sorder - sort order for a given folder. 226 */ 227 function getSortOrderForFolder($folderId) { 228 if(isset($_REQUEST['sorder']) && $_REQUEST['folderid'] == $folderId) { 229 $sorder = $this->db->sql_escape_string($_REQUEST['sorder']); 230 } elseif(is_array($_SESSION['NOTES_FOLDER_SORT_ORDER']) && 231 !empty($_SESSION['NOTES_FOLDER_SORT_ORDER'][$folderId])) { 232 $sorder = $_SESSION['NOTES_FOLDER_SORT_ORDER'][$folderId]; 233 } else { 234 $sorder = $this->default_sort_order; 235 } 236 return $sorder; 237 } 238 239 /** 240 * Function used to get the order by value for Documents listview 241 * @return String order by column for a given folder. 242 */ 243 function getOrderByForFolder($folderId) { 244 $use_default_order_by = ''; 245 if(PerformancePrefs::getBoolean('LISTVIEW_DEFAULT_SORTING', true)) { 246 $use_default_order_by = $this->default_order_by; 247 } 248 if (isset($_REQUEST['order_by']) && $_REQUEST['folderid'] == $folderId) { 249 $order_by = $this->db->sql_escape_string($_REQUEST['order_by']); 250 } elseif(is_array($_SESSION['NOTES_FOLDER_ORDER_BY']) && 251 !empty($_SESSION['NOTES_FOLDER_ORDER_BY'][$folderId])) { 252 $order_by = $_SESSION['NOTES_FOLDER_ORDER_BY'][$folderId]; 253 } else { 254 $order_by = ($use_default_order_by); 255 } 256 return $order_by; 257 } 258 259 /** Function to export the notes in CSV Format 260 * @param reference variable - where condition is passed when the query is executed 261 * Returns Export Documents Query. 262 */ 263 function create_export_query($where) 264 { 265 global $log,$current_user; 266 $log->debug("Entering create_export_query(". $where.") method ..."); 267 268 include ("include/utils/ExportUtils.php"); 269 //To get the Permitted fields query and the permitted fields list 270 $sql = getPermittedFieldsQuery("Documents", "detail_view"); 271 $fields_list = getFieldsListFromQuery($sql); 272 273 $userNameSql = getSqlForNameInDisplayFormat(array('first_name'=> 274 'vtiger_users.first_name', 'last_name' => 'vtiger_users.last_name'), 'Users'); 275 $query = "SELECT $fields_list, case when (vtiger_users.user_name not like '') then $userNameSql else vtiger_groups.groupname end as user_name" . 276 " FROM vtiger_notes 277 inner join vtiger_crmentity 278 on vtiger_crmentity.crmid=vtiger_notes.notesid 279 LEFT JOIN vtiger_attachmentsfolder on vtiger_notes.folderid=vtiger_attachmentsfolder.folderid 280 LEFT JOIN vtiger_users ON vtiger_crmentity.smownerid=vtiger_users.id " . 281 " LEFT JOIN vtiger_groups ON vtiger_crmentity.smownerid=vtiger_groups.groupid " 282 ; 283 $query .= getNonAdminAccessControlQuery('Documents',$current_user); 284 $where_auto=" vtiger_crmentity.deleted=0"; 285 if($where != "") 286 $query .= " WHERE ($where) AND ".$where_auto; 287 else 288 $query .= " WHERE ".$where_auto; 289 290 $log->debug("Exiting create_export_query method ..."); 291 return $query; 292 } 293 294 function del_create_def_folder($query) 295 { 296 global $adb; 297 $dbQuery = $query." and vtiger_attachmentsfolderfolderid.folderid = 0"; 298 $dbresult = $adb->pquery($dbQuery,array()); 299 $noofnotes = $adb->num_rows($dbresult); 300 if($noofnotes > 0) 301 { 302 $folderQuery = "select folderid from vtiger_attachmentsfolder"; 303 $folderresult = $adb->pquery($folderQuery,array()); 304 $noofdeffolders = $adb->num_rows($folderresult); 305 306 if($noofdeffolders == 0) 307 { 308 $insertQuery = "insert into vtiger_attachmentsfolder values (0,'Default','Contains all attachments for which a folder is not set',1,0)"; 309 $insertresult = $adb->pquery($insertQuery,array()); 310 } 311 } 312 313 } 314 315 function insertintonotesrel($relid,$id) 316 { 317 global $adb; 318 $dbQuery = "insert into vtiger_senotesrel values ( ?, ? )"; 319 $dbresult = $adb->pquery($dbQuery,array($relid,$id)); 320 } 321 322 /*function save_related_module($module, $crmid, $with_module, $with_crmid){ 323 }*/ 324 325 326 /* 327 * Function to get the primary query part of a report 328 * @param - $module Primary module name 329 * returns the query string formed on fetching the related data for report for primary module 330 */ 331 function generateReportsQuery($module,$queryplanner){ 332 $moduletable = $this->table_name; 333 $moduleindex = $this->tab_name_index[$moduletable]; 334 $query = "from $moduletable 335 inner join vtiger_crmentity on vtiger_crmentity.crmid=$moduletable.$moduleindex"; 336 if ($queryplanner->requireTable("vtiger_attachmentsfolder")){ 337 $query .= " inner join vtiger_attachmentsfolder on vtiger_attachmentsfolder.folderid=$moduletable.folderid"; 338 } 339 if ($queryplanner->requireTable("vtiger_groups".$module)){ 340 $query .= " left join vtiger_groups as vtiger_groups".$module." on vtiger_groups".$module.".groupid = vtiger_crmentity.smownerid"; 341 } 342 if ($queryplanner->requireTable("vtiger_users".$module)){ 343 $query .= " left join vtiger_users as vtiger_users".$module." on vtiger_users".$module.".id = vtiger_crmentity.smownerid"; 344 } 345 $query .= " left join vtiger_groups on vtiger_groups.groupid = vtiger_crmentity.smownerid"; 346 $query .= " left join vtiger_notescf on vtiger_notes.notesid = vtiger_notescf.notesid"; 347 $query .= " left join vtiger_users on vtiger_users.id = vtiger_crmentity.smownerid"; 348 if ($queryplanner->requireTable("vtiger_lastModifiedBy".$module)){ 349 $query .= " left join vtiger_users as vtiger_lastModifiedBy".$module." on vtiger_lastModifiedBy".$module.".id = vtiger_crmentity.modifiedby "; 350 } 351 return $query; 352 353 } 354 355 /* 356 * Function to get the secondary query part of a report 357 * @param - $module primary module name 358 * @param - $secmodule secondary module name 359 * returns the query string formed on fetching the related data for report for secondary module 360 */ 361 function generateReportsSecQuery($module,$secmodule,$queryplanner) { 362 363 $matrix = $queryplanner->newDependencyMatrix(); 364 365 $matrix->setDependency("vtiger_crmentityDocuments",array("vtiger_groupsDocuments","vtiger_usersDocuments","vtiger_lastModifiedByDocuments")); 366 $matrix->setDependency("vtiger_notes",array("vtiger_crmentityDocuments","vtiger_attachmentsfolder")); 367 368 if (!$queryplanner->requireTable('vtiger_notes', $matrix)) { 369 return ''; 370 } 371 // TODO Support query planner 372 $query = $this->getRelationQuery($module,$secmodule,"vtiger_notes","notesid", $queryplanner); 373 $query .= " left join vtiger_notescf on vtiger_notes.notesid = vtiger_notescf.notesid"; 374 if ($queryplanner->requireTable("vtiger_crmentityDocuments",$matrix)){ 375 $query .=" left join vtiger_crmentity as vtiger_crmentityDocuments on vtiger_crmentityDocuments.crmid=vtiger_notes.notesid and vtiger_crmentityDocuments.deleted=0"; 376 } 377 if ($queryplanner->requireTable("vtiger_attachmentsfolder")){ 378 $query .=" left join vtiger_attachmentsfolder on vtiger_attachmentsfolder.folderid=vtiger_notes.folderid"; 379 } 380 if ($queryplanner->requireTable("vtiger_groupsDocuments")){ 381 $query .=" left join vtiger_groups as vtiger_groupsDocuments on vtiger_groupsDocuments.groupid = vtiger_crmentityDocuments.smownerid"; 382 } 383 if ($queryplanner->requireTable("vtiger_usersDocuments")){ 384 $query .=" left join vtiger_users as vtiger_usersDocuments on vtiger_usersDocuments.id = vtiger_crmentityDocuments.smownerid"; 385 } 386 if ($queryplanner->requireTable("vtiger_lastModifiedByDocuments")){ 387 $query .=" left join vtiger_users as vtiger_lastModifiedByDocuments on vtiger_lastModifiedByDocuments.id = vtiger_crmentityDocuments.modifiedby "; 388 } 389 if ($queryplanner->requireTable("vtiger_createdbyDocuments")){ 390 $query .= " left join vtiger_users as vtiger_createdbyDocuments on vtiger_createdbyDocuments.id = vtiger_crmentityDocuments.smcreatorid "; 391 } 392 return $query; 393 } 394 395 /* 396 * Function to get the relation tables for related modules 397 * @param - $secmodule secondary module name 398 * returns the array with table names and fieldnames storing relations between module and this module 399 */ 400 function setRelationTables($secmodule){ 401 $rel_tables = array(); 402 return $rel_tables[$secmodule]; 403 } 404 405 // Function to unlink all the dependent entities of the given Entity by Id 406 function unlinkDependencies($module, $id) { 407 global $log; 408 /*//Backup Documents Related Records 409 $se_q = 'SELECT crmid FROM vtiger_senotesrel WHERE notesid = ?'; 410 $se_res = $this->db->pquery($se_q, array($id)); 411 if ($this->db->num_rows($se_res) > 0) { 412 for($k=0;$k < $this->db->num_rows($se_res);$k++) 413 { 414 $se_id = $this->db->query_result($se_res,$k,"crmid"); 415 $params = array($id, RB_RECORD_DELETED, 'vtiger_senotesrel', 'notesid', 'crmid', $se_id); 416 $this->db->pquery('INSERT INTO vtiger_relatedlists_rb VALUES (?,?,?,?,?,?)', $params); 417 } 418 } 419 $sql = 'DELETE FROM vtiger_senotesrel WHERE notesid = ?'; 420 $this->db->pquery($sql, array($id));*/ 421 422 parent::unlinkDependencies($module, $id); 423 } 424 425 // Function to unlink an entity with given Id from another entity 426 function unlinkRelationship($id, $return_module, $return_id) { 427 global $log; 428 if(empty($return_module) || empty($return_id)) return; 429 430 if($return_module == 'Accounts') { 431 $sql = 'DELETE FROM vtiger_senotesrel WHERE notesid = ? AND (crmid = ? OR crmid IN (SELECT contactid FROM vtiger_contactdetails WHERE accountid=?))'; 432 $this->db->pquery($sql, array($id, $return_id, $return_id)); 433 } else { 434 $sql = 'DELETE FROM vtiger_senotesrel WHERE notesid = ? AND crmid = ?'; 435 $this->db->pquery($sql, array($id, $return_id)); 436 437 $sql = 'DELETE FROM vtiger_crmentityrel WHERE (crmid=? AND relmodule=? AND relcrmid=?) OR (relcrmid=? AND module=? AND crmid=?)'; 438 $params = array($id, $return_module, $return_id, $id, $return_module, $return_id); 439 $this->db->pquery($sql, $params); 440 } 441 } 442 443 444 // Function to get fieldname for uitype 27 assuming that documents have only one file type field 445 446 function getFileTypeFieldName(){ 447 global $adb,$log; 448 $query = 'SELECT fieldname from vtiger_field where tabid = ? and uitype = ?'; 449 $tabid = getTabid('Documents'); 450 $filetype_uitype = 27; 451 $res = $adb->pquery($query,array($tabid,$filetype_uitype)); 452 $fieldname = null; 453 if(isset($res)){ 454 $rowCount = $adb->num_rows($res); 455 if($rowCount > 0){ 456 $fieldname = $adb->query_result($res,0,'fieldname'); 457 } 458 } 459 return $fieldname; 460 461 } 462 463 // Function to get fieldname for uitype 28 assuming that doc has only one file upload type 464 465 function getFile_FieldName(){ 466 global $adb,$log; 467 $query = 'SELECT fieldname from vtiger_field where tabid = ? and uitype = ?'; 468 $tabid = getTabid('Documents'); 469 $filename_uitype = 28; 470 $res = $adb->pquery($query,array($tabid,$filename_uitype)); 471 $fieldname = null; 472 if(isset($res)){ 473 $rowCount = $adb->num_rows($res); 474 if($rowCount > 0){ 475 $fieldname = $adb->query_result($res,0,'fieldname'); 476 } 477 } 478 return $fieldname; 479 } 480 481 /** 482 * Check the existence of folder by folderid 483 */ 484 function isFolderPresent($folderid) { 485 global $adb; 486 $result = $adb->pquery("SELECT folderid FROM vtiger_attachmentsfolder WHERE folderid = ?", array($folderid)); 487 if(!empty($result) && $adb->num_rows($result) > 0) return true; 488 return false; 489 } 490 491 /** 492 * Customizing the restore procedure. 493 */ 494 function restore($modulename, $id) { 495 parent::restore($modulename, $id); 496 497 global $adb; 498 $fresult = $adb->pquery("SELECT folderid FROM vtiger_notes WHERE notesid = ?", array($id)); 499 if(!empty($fresult) && $adb->num_rows($fresult)) { 500 $folderid = $adb->query_result($fresult, 0, 'folderid'); 501 if(!$this->isFolderPresent($folderid)) { 502 // Re-link to default folder 503 $adb->pquery("UPDATE vtiger_notes set folderid = 1 WHERE notesid = ?", array($id)); 504 } 505 } 506 } 507 508 function getQueryByModuleField($module, $fieldname, $srcrecord, $query) { 509 if($module == "MailManager") { 510 $tempQuery = split('WHERE', $query); 511 if(!empty($tempQuery[1])) { 512 $where = " vtiger_notes.filelocationtype = 'I' AND vtiger_notes.filename != '' AND vtiger_notes.filestatus != 0 AND "; 513 $query = $tempQuery[0].' WHERE '.$where.$tempQuery[1]; 514 } else{ 515 $query = $tempQuery[0].' WHERE '.$tempQuery; 516 } 517 return $query; 518 } 519 } 520 521 /** 522 * Function to check the module active and user action permissions before showing as link in other modules 523 * like in more actions of detail view. 524 */ 525 static function isLinkPermitted($linkData) { 526 $moduleName = "Documents"; 527 if(vtlib_isModuleActive($moduleName) && isPermitted($moduleName, 'EditView') == 'yes') { 528 return true; 529 } 530 return false; 531 } 532 } 533 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |