> var $PagerTop, $PagerBottom; // display pager at the top, at the bottom of the datagrid var $CommandsRight; // if true, edit/delete... commands are placed on the right, // or on the left when it is false var $ShowPageSizer; // show or hide drop down box which allows page size modification var $PagerSizes; // contains an array of values as a pager sizes. See how it is initizlied in the constructor var $Columns; // the collection of columns // private fields var $db; // data base operations manager class var $clientID; // client id for this class. created automatically. important for post back operations var $sort_field, $sort_ascending; // the index of sorting field and the sort direction var $editItemID; // the id of item currently being edited. var $toolbarCommands; // collection of toolbar commands var $onInsert, $onEdit, $onUpdate, $onDelete; // call back functions var $Title, $TitleCols; var $CellFontSize; // filter variables... var $AllowFilter, $ClearAllFilters, $AutoWhereClause; // the constructor. you can pass into it interface holder template function DataGrid ($template_file = NULL) { global $TPL_FOLDER, $RashadsDataGridInstancesCount; //$RashadsDataGridInstancesCount ++; // see the first lines of this file for more info // if no template is provided, it loads the default template and translates it $this->Template = new Template(); $this->Template->LoadFile( isset($template_file)?$template_file:"datagrid.tpl"); // initing functionality modifiers $this->AllowInsert = true; $this->ShowCaption = true; $this->AllowEdit = true; $this->AllowDelete = true; $this->AllowSelect = true; $this->AllowPage = true; $this->AllowSort = true; $this->AllowFilter = true; $this->AllowDeleteSelected = true; $this->AllowCancelSort = true; $this->ShowPageSizer = true; $this->PageSize = 20; $this->PagerCount = 10; $this->PagerTop = false; $this->PagerBottom = true; $this->CommandsRight = true; $this->CurrentPage = 0; $this->Title =""; $this->TitleCols =0; $this->PagerSizes = array("1","5","10","20","30","40","50","70","100"); $this->SelectSQL = NULL; // database management settings $this->AllowAutoIncrement = true; $this->KeyField = "id" ; $this->TableName = ""; $this->WhereClause = NULL; $this->AutoWhereClause = NULL; $this->OrderByClause = NULL; $this->Columns = array(); $this->db = new DB(); $this->sort_field = NULL; $this->sort_ascending = true; $this->editItemID = NULL; $this->error_message = NULL; $this->onInsert = NULL; $this->onUpdate = NULL; $this->toolbarCommands = array(); $this->CellFontSize = 12; } // registers the call back function for insert command function OnInsertCall($callBack) { $this->onInsert = $callBack; } // registers the call back function for update command function OnUpdateCall($callBack) { $this->onUpdate = $callBack; } // registers the call back function for delete command function OnDeleteCall($callBack) { $this->onDelete = $callBack; } // registers the call back function for edit command function OnEditCall($callBack) { $this->onEdit = $callBack; } // this function is called when the "Delete Selected" on the toolbar is clicked function DeleteSelected($values) { // if no row is selected if (! isset ($values) || count($values) == 0) { $this->error_message = "No row selected to delete"; return; } // get the nail, if the sql should be like "WHERE id='1' " or "WHERE id=1" $nail = $this->GetNail($this->KeyFieldType()); $sql = "DELETE FROM $this->TableName Where "; // prepare SQL $canIncludeOr = false; for ($i=0; $idb->Execute($sql)) $this->error_message = "Error occured. Cannot delete selected rows"; } // This function is automatically called when the Cancel Sorting pressed on the toolbar function CancelSorting() { $this->sort_field = NULL; } // This function registers a new toolbar command // $templare is an instance of Template class // $callback is the function which will be called when this button is clicked function RegisterToolbarCommand($commandName, $template, $callBack) { $command = new DataGridToolbarCommand($commandName, $template, $callBack); $this->toolbarCommands[] = $command; } // add a new text box column. it displays the data normal. but displays text box for editing it function AddTextBoxColumn ($field_name, $caption, $canSort = true) { $newCol = new DataGridTextBoxColumn ($field_name, $caption, $canSort); $this->Columns[] = $newCol; } function AddCalendarColumn ($field_name, $caption) { $newCol = new DataGridCalendarColumn ($field_name, $caption); $this->Columns[] = $newCol; } // add a new combo box column. See DataGridComboColumn for more info function AddComboColumn ($field_name, $caption, $options) { $newCol= new DataGridComboColumn ($field_name, $caption); $newCol->CanShow = true; $newCol->CanSort = true; $newCol->CanEdit = true; if (isset($options) && is_array($options)) { $a = array_keys($options); for ($i=0; $iAddOption($a[$i], $options[$a[$i]]); } } $this->Columns[] = $newCol; } function AddTriStateColumn ($field_name, $caption) { $newCol = new DataGridTriStateColumn ($field_name, $caption); $this->Columns[] = $newCol; } function AddCheckBoxColumn ($field_name, $caption, $true_text = "True", $false_text = "False") { $newCol = new DataGridCheckColumn ($field_name, $caption, $true_text, $false_text); $this->Columns[] = $newCol; } // creates a new client id for this datagrid function CreateClientID() { global $RashadsDataGridInstancesCount; return "DataGrid_$this->TableName$RashadsDataGridInstancesCount"; } // calls the insert handler or inserts a new row function InsertNew() { // if insertion is not allowed if (! $this->AllowInsert || $this->editItemID != NULL) return; // if the developer listens for listen command if ( isset ($this->onInsert) ) { $retValue = array(); for ($i=0; $iColumns); $i++) { // instance of works only on PHP 5. So, if you are using PHP 5, // and want to have this type check, uncomment all of the instanceof fragments if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn ||*/ $this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; $this->Columns[$i]->Init(NULL, NULL, $this); $retValue[] = $this->Columns[$i]->GetValue(); } $cancel = false; call_user_func_array($this->onInsert, array(&$retValue, &$cancel)); if ($cancel) return; else { for ($i=0; $iColumns); $i++) { $this->Columns[$i]->SetValue($retValue[$i]); } } } // see if Key Field is in the list of fields $isIn = false; for ($i=0; $iColumns); $i++) { if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || */ $this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; if ($this->KeyField == $this->Columns[$i]->FieldName) { $isIn = true; break; } } // prepare sql $insertSQL = "INSERT INTO $this->TableName ("; $canInsertColon = false; // should we increment key field, or does the user specify it? if ($this->AllowAutoIncrement && !$isIn) { $sql = "SELECT max($this->KeyField) FROM $this->TableName"; $max = ((int)$this->db->GetScalar($sql)) + 1; $insertSQL .= "$this->KeyField"; $canInsertColon = true; } // insert field names for ($i=0; $iColumns); $i++) { // instance of doesn't work on PHP 4 if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || $this->Columns[$i] instanceof DataGridCommandColumn || */ $this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; if (! $canInsertColon) $canInsertColon = true; else $insertSQL .= ", "; $insertSQL.= $this->Columns[$i]->FieldName; } $insertSQL .= ") VALUES ("; // insert values if ($this->AllowAutoIncrement && !$isIn) { $insertSQL .= "$max"; $canInsertColon = true; } else $canInsertColon = false; $nail = "'"; for ($i=0; $iColumns); $i++) { if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || */ $this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; if (! $canInsertColon) $canInsertColon = true; else $insertSQL .= ", "; $this->Columns[$i]->Init(NULL, NULL, $this); $insertSQL.= "$nail".$this->Columns[$i]->GetValue()."$nail"; } $insertSQL .= ")"; if (!$this->db->Execute($insertSQL) ) $this->error_message = "Error occured. Cannot execute the insert sql."; } // clear the filter function ClearFilter() { // if insertion is not allowed if (! $this->AllowFilter) return; $this->AutoWhereClause=""; $this->ClearAllFilters=true; } // set the filter function ChangeFilter() { // if insertion is not allowed if (! $this->AllowFilter) return; if ($this->ClearAllFilters == true) { $this->ClearAllFilters=false; return; } // prepare where $wheresql = ""; $canInsertColon = false; // insert field names for ($i=0; $iColumns); $i++) { // instance of doesn't work on PHP 4 if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || $this->Columns[$i] instanceof DataGridCommandColumn || */ $this->Columns[$i]->CanShow==false) continue; $this->Columns[$i]->Init(NULL, NULL, $this); $fname = $this->Columns[$i]->FieldName; $fvalue = $this->Columns[$i]->GetFilterValue(); if ($fvalue != "") { if (! $canInsertColon) $canInsertColon = true; else $wheresql .= " and "; $nail = "'"; $filters = split(",", $fvalue); if (count($filters) > 1) { $wheresql .= "("; foreach ($filters as $f => $v) { if (strlen($v) > 0) $wheresql .= "$fname like $nail$v$nail"; else $wheresql .= "$fname='' or $fname is null"; if ($f != count($filters)-1) $wheresql .= " or "; } $wheresql .= ")"; } else { $wheresql.= "$fname like $nail$fvalue$nail"; } } } $this->AutoWhereClause=$wheresql; } function SetTitle($t, $c) { $this->Title = $t; $this->TitleCols = $c; } // This function initializes data grid. Respotores state from hidden fields function InitDataGrid() { // registering toolbar commands if ($this->AllowCancelSort) $this->RegisterToolbarCommand("cancelSorting", $this->Template->Find("cancelSorting"), array("DataGrid", "CancelSorting")); if ($this->AllowDeleteSelected) $this->RegisterToolbarCommand("deleteSelected", $this->Template->Find("deleteSelected"), array("DataGrid", "DeleteSelected")); // getting settings from hidden value $setting = POST_PARAM("settingsof$this->clientID"); // if no setting, no need to analyze if ( ! isset($setting) || trim ($setting) == "") return; // split the string into array $settings = explode (";",$setting); // and analyze every setting for ($i=0; $iShowCaption) $this->sort_field = $pieces[1]; break; case "asc": $this->sort_ascending = $pieces[1]; break; case "curpage": $this->CurrentPage = (int)$pieces[1]; break; case "psize": $this->PageSize = (int)$pieces[1]; break; case "edit": $this->editItemID = (int)$pieces[1]; } } } // this is a private variable. If command occured, selection checkboxes will be dropeed var $CommandOccured = false; // Processes post back data. When a link of this datagrid is licked the this function handles it function ProcessPostData() { // getting the sender the post back event and the event's arguments $target = POST_PARAM("__eventtarget"); if (! isset($target) || $target!= $this->clientID) return; $argument = POST_PARAM("__eventargument"); if (! isset ($argument) || trim($argument) == "") return; // split settings as name and value $pieces = explode ("=", $argument); // lets stop editing and display that row normal $this->editItemID = NULL; // and drop the selection checkboxes $this->CommandOccured = true; switch (trim($pieces[0])) { case "sort": if ($this->sort_field == (int)$pieces[1]) $this->sort_ascending =! $this->sort_ascending; else $this->sort_ascending = true; $this->sort_field = (int)$pieces[1]; break; case "goto": $this->CurrentPage = (int)$pieces[1]; break; case "pagesize": $this->CurrentPage = 0; $this->PageSize = (int)$pieces[1]; break; case "edit": if (isset ($this->onEdit) ) { call_user_func_array($this->onEdit, array($pieces[1], &$cancel)); if ($cancel) return; } $this->editItemID = (int)$pieces[1]; break; case "cancel": break; case "update": $this->Update((int)$pieces[1]); break; case "insertNew": $this->InsertNew(); break; case "clearFilter": $this->ClearFilter(); break; case "changeFilter": break; case "delete": // is the developer listening for delete command? if (isset ($this->onDelete) ) { call_user_func_array($this->onDelete, array($pieces[1], &$cancel)); if ($cancel) return; } // can we autimatically create delete SQL? if (!isset ($this->TableName) || $this->TableName=="") { $this->error_message = "No TableName property has not been initialized to automatically generate delete sql"; return; } $nail = $this->GetNail($this->KeyFieldType()); $sql = "DELETE FROM $this->TableName Where $this->KeyField=".$nail ."$pieces[1]".$nail; if (! $this->db->Execute("$sql")) $this->error_message = "Error occured. Cannot delete this row."; break; default: // searching in toolbar Commands $executed = false; if ( count($this->toolbarCommands)>0 ) { for ($i=0; $itoolbarCommands); $i++) { if (trim($this->toolbarCommands[$i]->commandName) == trim($pieces[0])) { call_user_func ($this->toolbarCommands[$i]->callBackFunction, $this->GetSelectedValues()); $executed = true; break; } } } // searching in command fields if (! $executed) for ($i=0; $iColumns); $i++) { /*if (! $this->Columns[$i] instanceof DataGridCommandColumn) continue;*/ if ($this->Columns[$i]->CommandName == $pieces[0]) { call_user_func_array ($this->Columns[$i]->Callback, array($pieces[1])); $executed = true; break; } } break; } } // it returns the type of keyfield function KeyFieldType() { $sql = "SELECT $this->KeyField FROM $this->TableName limit 1,1"; $result = $this->db->GetResult($sql); if (! isset ($result)) { $this->error_message = "Error occured. Cannot get key field"; } return (string)mysql_field_type($result, 0); } // updates the table or calls the developers update handler function function Update($id) { // for call back firing if ( isset ($this->onUpdate) ) { $retValue = array(); for ($i=0; $iColumns); $i++) { if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || */$this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; $this->Columns[$i]->Init(NULL, NULL, $this); $retValue[] = $this->Columns[$i]->GetValue(); } $cancel = false; call_user_func_array($this->onUpdate, array($id, $retValue, &$cancel)); if ($cancel) return; } // checking current state if ( isset ($this->SelectSQL) ) { $this->error_message = "You have set special sql to select data. DataGrid cannot generate automatic update statement. user OnUpdateCall() method to specify your own update statement."; return; } if (! isset ($this->TableName) || $this->TableName == "") { $this->error_message = "You must set TableName property to a valid value so that DataGrid could generate a valid update query."; return; } // updating $newValue = array(); $sql = "UPDATE $this->TableName Set "; $colon = true; $nail = ""; $colCount = 0; for ($i=0; $iColumns); $i++) { if (/*! ($this->Columns[$i] instanceof DataGridColumn) || $this->Columns[$i] instanceof DataGridCommandColumn || */$this->Columns[$i]->CanShow==false || $this->Columns[$i]->CanEdit==false) continue; if ($colon) $colon = false; else $sql .= ", "; $colCount ++; $this->Columns[$i]->Init(NULL, NULL, $this); $nail = "'"; $sql.= $this->Columns[$i]->FieldName."=$nail".$this->Columns[$i]->GetValue()."$nail"; } if ($colCount == 0) $this->error_message = "No column to update"; else { $nail = $this->GetNail($this->KeyFieldType()); $sql .= " WHERE $this->KeyField=".$nail."$id".$nail; if (!$this->db->Execute($sql)) { $this->error_message = "Error occured. Cannot update"; } } } // this function returns the array which holds the key fields ids for selected rows function GetSelectedValues() { return POST_PARAM($this->CreateClientID()); } // returns if nail (') should be included for such field type or not function GetNail ($typeOfField) { $typeOfField = strtolower(trim($typeOfField)); switch ($typeOfField) { case "int": case "tinyint": case "smallint": case "mediumint": case "integer": case "bigint": case "bit": case "bool": case "boolean": case "double": case "float": case "unsigned": case "decimal": case "dec": return ""; default: return "'"; } } // cache count or rows var $countOfRows; // gets the count of rows for paging purposes // limit should not be included in here to get real count of rows function getCountOfRows() { if ( isset ($this->countOfRows)) return $this->countOfRows; $sql = $this->PrepareSQL(false); $a = $this->db->GetResult($sql); $this->countOfRows = mysql_num_rows($a); return $this->countOfRows ; } // prepares sql statement to select data from table function PrepareSQL($includeLimit = true) { //if developer has specified the sql to select data $sql = ""; if ( isset ($this->SelectSQL) ) $sql = $this->SelectSQL; else { // otherwise create it yourself $sql = "SELECT $this->KeyField"; for ($i=0; $iColumns); $i++) { if ( /*! ($this->Columns[$i] instanceof DataGridColumn) || */$this->Columns[$i]->FieldName==$this->KeyFieldName) continue; $sql .= ", "; $sql .= $this->Columns[$i]->FieldName; } $sql .= " FROM $this->TableName "; if (isset ($this->WhereClause) && trim($this->WhereClause)!="") $sql .= " WHERE $this->WhereClause"; if (isset ($this->AutoWhereClause) && trim($this->AutoWhereClause)!=""){ if (isset ($this->WhereClause) && trim($this->WhereClause)!="") $sql .= " AND $this->AutoWhereClause"; else $sql .= " WHERE $this->AutoWhereClause"; } } // can we include order by? if ( $includeLimit && $this->AllowSort && isset($this->sort_field) && trim($this->sort_field)!="") $sql .= " ORDER BY ".$this->Columns[$this->sort_field]->FieldName." ".($this->sort_ascending?"ASC ":"DESC "); if (isset ($this->OrderByClause) && !$this->AllowSort) $sql .= " ORDER BY ".$this->OrderByClause; // can we include limit? if ($includeLimit && $this->AllowPage) { $start = $this->CurrentPage*$this->PageSize; $sql .= " limit $start, $this->PageSize"; } return $sql; } // returns the number of columns of the table to be rendered. // needed for colspan property of some TDs function getCountOfCols() { $cnt = 0; for ($i=0; $iColumns); $i++) { if ($this->Columns[$i]->CanShow) $cnt ++; } if ($this->AllowEdit || $this->AllowDelete || $this->AllowInsert) $cnt ++; if ($this->AllowSelect) $cnt ++; return (int)$cnt; } // renders the pager bar. function RenderPager($result) { $totalCount = $this->getCountOfRows(); $countOfPages = ceil($totalCount / $this->PageSize); $pager = $this->Template->Find("pager"); $cnt = $this->getCountOfCols(); $pager->Put("count", "".$cnt); // see about the goto first button if ($this->CurrentPage == 0) { $gotoFirstButton = $pager->Find("goto_first_passive"); $pager->Apply($gotoFirstButton); $gotoFirstButton = $pager->Find("goto_first_active"); $gotoFirstButton->output = ""; $pager->Apply($gotoFirstButton); } else { $gotoFirstButton = $pager->Find("goto_first_active"); $gotoFirstButton->Put("goto_first", $this->PostBackLink("goto=0")); $pager->Apply($gotoFirstButton); $gotoFirstButton = $pager->Find("goto_first_passive"); $gotoFirstButton->output = ""; $pager->Apply($gotoFirstButton); } // see about the goto last button if ($countOfPages==0 || $this->CurrentPage == ($countOfPages-1)) { $gotoLastButton = $pager->Find("goto_last_passive"); $pager->Apply($gotoLastButton); $gotoLastButton = $pager->Find("goto_last_active"); $gotoLastButton->output = ""; $pager->Apply($gotoLastButton); } else { $gotoLastButton = $pager->Find("goto_last_active"); $gotoLastButton->Put("goto_last", $this->PostBackLink("goto=".($countOfPages-1))); $pager->Apply($gotoLastButton); $gotoLastButton = $pager->Find("goto_last_passive"); $gotoLastButton->output = ""; $pager->Apply($gotoLastButton); } // get the pager item and the selected item $item = $pager->Find("pageritem"); $item->output = ""; $si= $pager->Find("selecteditem"); $selectedItem = $pager->Find("selecteditem"); $si->output = ""; $pager->Apply($si); // calculate the range of pager links. from and to $from = (int)0; $to = (int)$countOfPages; if ($countOfPages>$this->PagerCount) { $from = (ceil(($this->CurrentPage +1)/$this->PagerCount)-1)*$this->PagerCount; $from = max(0, $from); $to = $from + $this->PagerCount; if ($to>$countOfPages) $to = $countOfPages; } // put special "..." buttons if we are too far from the first page if ($from > 0) { $item->Repeat(); $item->Put("goto_page", $this->PostBackLink("goto=".($from-1))); $item->Put("page_number", "..."); } // render pager links for ($i=$from; $i<$to; $i++) { if ($i == $this->CurrentPage) { $selectedItem->Put("selected_page_number", "".($i+1)); $item->output .= $selectedItem->output; } else { $item->Repeat(); $item->Put("goto_page", $this->PostBackLink("goto=$i")); $item->Put("page_number", "".($i+1)); } } // put special ... buttons if we are too far from the last page if ($to < $countOfPages) { $item->Repeat(); $item->Put("goto_page", $this->PostBackLink("goto=$to")); $item->Put("page_number", "..."); } $pager->Apply($item); // rendering pager if ($this->ShowPageSizer) { $sizes = $this->PagerSizes; $command = "javascript: __doPostBack('$this->clientID', 'pagesize='+this.options[this.selectedIndex].value)"; $str = "Page Size".": "; $pager->Put("page_sizer", $str); } else $pager->Put("page_sizer", ""); $this->write($pager->output); } // renders the toolbar and the error message function RenderToolbar() { $cnt = $this->getCountOfCols(); //if we have any toolbar buttons to be rendered if ( count($this->toolbarCommands)!=0 ) { $toolbar = $this->Template->Find("toolbar"); if (! isset ($toolbar)) $this->error_message = "Could not find toolbar fragment in the template file"; else { if ($this->TitleCols == 0) { $toolbar->Put("counttitle", "1"); $toolbar->Put("count", "".($cnt-1)); } else { $toolbar->Put("counttitle", "".$this->TitleCols); $toolbar->Put("count", "".($cnt-$this->TitleCols)); } $toolbar->Put("title", "".$this->Title); $seperator = NULL; $result = ""; for ($i=0; $itoolbarCommands); $i++) { if (!isset($seperator)) $seperator = $this->Template->Find("command_seperator"); else $result .= $seperator->output; if (isset($this->toolbarCommands[$i]->template)) $this->toolbarCommands[$i]->template->Put("link", $this->PostBackLink($this->toolbarCommands[$i]->commandName)); else $this->error_message = "Could not find template for ".$this->toolbarCommands[$i]->commandName; $result .= $this->toolbarCommands[$i]->template->output; } $toolbar->Put("commands", $result); $this->write($toolbar->output); } } // see about the error message field $error_info = $this->Template->Find("error"); $error_info->Put("count", "".$cnt); if (isset($this->error_message)) $error_info->Put("error_message", $this->error_message); else $error_info->Clear(); $this->write($error_info->output); // render error } // the buffer. If you pass true into the render button. It won't write it to the page, // instead it will return you the output. The return outpur is stored in it var $the_buffer = NULL; // calls datagrid initzializations, post back processot, sql generator, etc... // and renders the datagrid. If you pass true as a parameter it will return the output, not write to the page function Render($buffer = false) { // Should we store output? $this->the_buffer = $buffer?"":NULL; $this->clientID = $this->CreateClientID(); // creating client id. very important for datagrids functionality $this->InitDataGrid(); // Initialize the datagrid $this->ProcessPostData(); // process postback data $this->ChangeFilter(); $sql = $this->PrepareSQL(); // prepare sql to acquire data $this->RegisterClientScripts(); // register the important client scripts // Loading the HTML template $table_start = $this->Template->Find("table"); $item_row = $this->Template->Find("item_row"); $alternating_row = $this->Template->Find("alternating_row"); $item_cell = $this->Template->Find("item_cell"); $alternating_cell = $this->Template->Find("alternating_cell"); $header_row = $this->Template->Find("header_row"); $header = $this->Template->Find("header"); $ascending_arrow = $this->Template->Find("asc"); $descending_arrow = $this->Template->Find("desc"); $sorted_cell = $this->Template->Find("sorted_cell"); $alt_sorted_cell = $this->Template->Find("alternating_sorted_cell"); $table_close = $this->Template->Find("table_close"); $tools_caption = $this->Template->Find("tools_caption"); $result = $this->db->GetResult($sql); // load result if (! isset($result)) $this->error_message = "Error occured. Cannot select"; // calculate the table width $tblw = 0; for ($i=0; $iColumns); $i++) { if ($this->Columns[$i]->CanShow != true) continue; if ( isset ($this->Columns[$i]->Width)) { $tblw += $this->Columns[$i]->Width; } } // print " tblw:$tblw : " . $table_start->output . "
"; // if ($tblw > 0) { // if ($this->AllowSelect) $tblw += 25; // if ($this->AllowEdit || $this->AllowDelete) $tblw += 350; // $table_start->Put("twidth", "width=\"".$tblw."px\""); // } // else { $table_start->Put("twidth", ""); // } // print " tblw:$tblw : " . $table_start->output . ""; // Starting table $this->write($table_start->output); $this->RenderToolbar(); // rendering toolbar if ($this->AllowPage && $this->PagerTop) // if paging is allowed render pager $this->RenderPager($result); if ($this->ShowCaption) { $this->write($header_row->output); // render caption // let users to select rows if ($this->AllowSelect) { $header->Put("width", "1px"); $this->write($header->output); $topCheckBoxChecked = ""; if (! $this->CommandOccured) { $topCheckBoxChecked= POST_PARAM("$this->clientID-topCheckBox"); $topCheckBoxChecked = $topCheckBoxChecked[0]=="on"?" checked ":" not "; } $this->write("clientID-topCheckBox\" name=\"$this->clientID-topCheckBox[]\" $topCheckBoxChecked onclick=\"javascript: SelectAllRowsOfDataGrid('$this->clientID', '$this->PageSize')\">"); $this->write(""); $header->Clear(); $header->Repeat(); $header->Put("width",""); } // if commands should be placed on the left, render Tools caption if ( !$this->CommandsRight==true && ($this->AllowEdit || $this->AllowDelete)) { $this->write($header->output); $this->write( $tools_caption->output); $this->write(""); } // render caption names, at the same allowing sorting or not for ($i=0; $iColumns); $i++) { if ($this->Columns[$i]->CanShow != true) continue; $header->output = $header->original; if ( isset ($this->Columns[$i]->Width)) { $header->Put("width",$this->Columns[$i]->Width); } $this->write($header->output); if ($this->AllowSort && $this->Columns[$i]->CanSort) $this->write("PostBackLink("sort=$i")."\">"); $this->write($this->Columns[$i]->Caption); if ($this->AllowSort && isset($this->sort_field) && $this->Columns[$i]->CanSort) { $this->write(""); if ($i == $this->sort_field) { $this->write(($this->sort_ascending?$ascending_arrow->output:$descending_arrow->output)); } } $this->write("\n\t\t\n"); } // end of rendering table caption } // if commands on the right, render their caption $header->output = $header->original; $header->Put("width",""); if ( $this->ShowCaption && $this->CommandsRight==true && ($this->AllowEdit || $this->AllowDelete)) { $this->write($header->output); $this->write( $tools_caption->output); $this->write(""); } $this->write("\n\n"); if ($this->AllowFilter) { $this->RenderFilterRow(); } // if no result to display? report about it if (! isset ($result) || mysql_num_rows($result) == 0) { $this->write($item_row->output); $this->write($item_cell->output); $this->write(" "); $this->write($item_cell->output); $this->write (""."No data to display here".""); } else { // if we have rows to render, render them to user $is_alternating = true; // to manage item and alternating item styles $chbID = 0; // to assign id's to selection checkoxes $row_template; //get the template $selectedRows = $this->GetSelectedValues(); // get selected rows to check the selection boxes // iterate through rows while ($row = mysql_fetch_array($result)) { $row_template = $is_alternating?$item_row:$alternating_row; $row_template->Put("id", $this->clientID."_row_$chbID"); $this->write($row_template->output); // start row // render selection chechboxes if ($this->AllowSelect) { $this->write($is_alternating?$item_cell->output:$alternating_cell->output); $this->write("clientID.checkBox$chbID\" name=\"$this->clientID"."[]\" value=\"".$row[$this->KeyField]."\""); if (isset ($this->CommandOccured) && $this->CommandOccured==false && isset ($selectedRows) && in_array($row[$this->KeyField], $selectedRows)) $this->write(" checked"); $this->write(" >"); $this->write(""); $chbID ++; } // render tools (edit, delet, update, cancel) $this->RenderTools($row, true, $is_alternating); // rendering rows itself for ($i=0; $iColumns); $i++) { // only if the column's CanShow is true if ($this->Columns[$i]->CanShow != true) continue; $cell_template; // if it is sorted, render different design if ($this->AllowSort && isset($this->sort_field) && $this->Columns[$i]->CanSort && $i == $this->sort_field) { $cell_template = $is_alternating?$sorted_cell:$alt_sorted_cell; } else { $cell_template = $is_alternating?$item_cell:$alternating_cell; } // initialize the column $this->Columns[$i]->Init($row[$this->Columns[$i]->FieldName], $row, $this); $v = substr($this->Columns[$i]->Value, 0, 1); if ($v == "!") { // change the cell color and render it $cell_template->Put("linet", "style=\"color: red; text-decoration: line-through;\""); } else { $cell_template->Put("linet", ""); } $this->write($cell_template->output); $cell_template->output = $cell_template->original; if (isset ($row[$this->KeyField]) && $row[$this->KeyField] == $this->editItemID && $this->Columns[$i]->CanEdit==true) { // render editing mode $this->write($this->Columns[$i]->RenderEdit()); } else // render normal $this->write($this->Columns[$i]->Render()); $this->write("\n\t\t\n"); } // render tools on the right side $this->RenderTools($row, false, $is_alternating); $this->write("\n\t\n"); $is_alternating = ! $is_alternating; } } // if user is eligible to insert if ($this->AllowInsert) { $this->RenderInsertableRow(); } // conclusion ;) if ($this->AllowPage && $this->PagerBottom) $this->RenderPager($result); $this->write($table_close->output); if ( $buffer ) return $this->the_buffer; } // renders a special row which allows users to insert a new record function RenderFilterRow() { if (! $this->AllowFilter ) return; // load templates $tr = $this->Template->Find("filter_row"); $td = $this->Template->Find("filter_cell"); $btn = $this->Template->Find("filter_command"); $fcmd = $this->Template->Find("filter_cellcmd"); $btn->Put("link", $this->PostBackLink("clearFilter")); $fcmd->Put("link", $this->PostBackLink("changeFilter")); // starting row $this->write($tr->output); if ($this->AllowSelect) $this->write($td->output.$star->output.""); if ($this->CommandsRight == false) $this->write($btn->output.$fcmd->output.""); // render edit mode for each editable row for ($i = 0; $i < count($this->Columns); $i++) { if ( /*! ($this->Columns[$i] instanceof DataGridColumn) || */$this->Columns[$i]->CanShow==false) continue; $this->write ($td->output); $this->Columns[$i]->Init(NULL, NULL, $this); $this->write($this->Columns[$i]->RenderFilter()); //$this->write ($fcmd->output.""); $this->write (""); } if ($this->CommandsRight) $this->write($btn->output.$fcmd->output.""); $this->write(""); } // renders a special row which allows users to insert a new record function RenderInsertableRow() { if (! $this->AllowInsert || $this->editItemID!=NULL ) return; // load templates $tr = $this->Template->Find("insert_row"); $td = $this->Template->Find("insert_cell"); $btn = $this->Template->Find("insert_command"); $star = $this->Template->Find("insert_star"); $btn->Put("link", $this->PostBackLink("insertNew")); // starting row $this->write($tr->output); // if can select? render asterisk if ($this->AllowSelect) $this->write($td->output.$star->output.""); if ($this->CommandsRight == false) $this->write($btn->output); // render edit mode for each editable row for ($i = 0; $i < count($this->Columns); $i++) { if ( /*! ($this->Columns[$i] instanceof DataGridColumn) || */$this->Columns[$i]->CanShow==false) continue; $this->write ($td->output); $this->Columns[$i]->Init(NULL, NULL, $this); if ($this->Columns[$i]->CanEdit==true) { $this->write($this->Columns[$i]->RenderEdit()); } else { $this->write(" "); } $this->write (""); } if ($this->CommandsRight) $this->write($btn->output); $this->write(""); } // caching buttons var $editButton , $updateButton, $cancelButton, $deleteButton, $command_seperator; var $tools_cell, $alt_tools_cell; // renders tools such as edit, delete, update, delete function RenderTools ($row, $command_positon, $is_alternating) { if ($this->CommandsRight == $command_positon || ($this->AllowEdit==false && $this->AllowDelete==false)) return; // if tools' template has already been initialized, use them // if not initizlize them // init tools normal cell if (!isset($this->tools_cell)) $this->tools_cell = $this->Template->Find("tools_cell"); //init tools alternating cell if (!isset($this->alt_tools_cell)) $this->alt_tools_cell = $this->Template->Find("alternating_tools_cell"); // initing edit, update and cancel button if ($this->AllowEdit) { if ( !isset($this->editButton)) { $this->editButton = $this->Template->Find("edit"); } if ( !isset($this->updateButton)) $this->updateButton = $this->Template->Find("update"); if ( !isset($this->cancelButton)) $this->cancelButton = $this->Template->Find("cancel"); } // including delete button if ($this->AllowDelete) { if (!isset ($this->deleteButton)) $this->deleteButton = $this->Template->Find("delete"); } // initializing command seperator if (!isset ($this->command_seperator)) $this->command_seperator= $this->Template->Find("command_seperator"); // starting row $this->write($is_alternating?$this->tools_cell->output:$this->alt_tools_cell->output); // putting key field id and creating post back link for them if ( $this->AllowEdit) { if ($row[$this->KeyField] == $this->editItemID) { // editing mode commands go here $this->updateButton->Clear(); $this->updateButton->Repeat(); $this->updateButton->Put("link", $this->PostBackLink("update=".$row[$this->KeyField])); $this->write( $this->updateButton->output ); $this->write($this->command_seperator->output); $this->cancelButton->Clear(); $this->cancelButton->Repeat(); $this->cancelButton->Put("link", $this->PostBackLink("cancel=".$row[$this->KeyField])); $this->write( $this->cancelButton->output ); } else { // non editing mode commands $this->editButton->Clear(); $this->editButton->Repeat(); $this->editButton->Put("link", $this->PostBackLink("edit=".$row[$this->KeyField])); $this->write( $this->editButton->output ); } } // init and render delete command if ($this->AllowDelete && ($row[$this->KeyField] != $this->editItemID)) { if ($this->AllowEdit) $this->write($this->command_seperator->output); $this->deleteButton->Clear(); $this->deleteButton->Repeat(); $this->deleteButton->Put("link", $this->PostBackLink("delete=".$row[$this->KeyField])); $this->write( $this->deleteButton->output ); } // endgin row $this->write(""); } // writes the given string to buffer or to the page function write ($str) { if ( isset($this->the_buffer)) $this->the_buffer .= $str; else echo ("$str"); } // Registers the client side scripts and CSS style sheets function RegisterClientScripts() { // saving settings $hidden = "edit=$this->editItemID;psize=$this->PageSize;curpage=$this->CurrentPage;sortfield=$this->sort_field;asc=".($this->sort_ascending?1:0).";"; $this->write("clientID\" value=\"$hidden\">"); // getting css specific for only this template $datagrid_css = $this->Template->Find("datagrid_css"); // getting client side script which is unicall for all instances and all templates $selectAll = $this->Template->Find("datagrid_selectAll_script"); // retister the java script if (!IsClientScriptRegistered("Rashad's Data Grid Select All Script")) { RegisterClientScript("Rashad's Data Grid Select All Script", NULL); $this->write($selectAll->output); } // register css if (!IsClientScriptRegistered("cssof".$this->Template->file_name)) { RegisterClientScript("cssof".$this->Template->file_name, NULL); $datagrid_css->Put("CellFontSize", "".$this->CellFontSize); $this->write($datagrid_css->output); } // register special hidden fields and javascript block which enables post backs if (IsClientScriptRegistered("postBackScripts")) return; $script = "\n"; // value=\"".POST_PARAM("__eventtarget")."\">\n"; $script .= ""; // value=\"".POST_PARAM("__eventargument")."\">\n"; $script .= "\n"; RegisterClientScript("postBackScripts", NULL); $this->write($script); } // creates a post back link specific only to this instance of datagrid function PostBackLink ($argument) { return "javascript: __doPostBack('$this->clientID','$argument');"; } } /*********************************************************************************************/ // base class for all columns of datagrid class DataGridColumn { var $FieldName; // The name of field in the table var $Caption; // Caption for this Columns var $Value; // This is the value that this column is to display. var $CanSort; // Can this Column be sorted? var $CanEdit; // Can this Column be edited? var $CanShow; // Is this column displayed? If event not, $this->Row will contain it's data var $Parent; // The reference to its DataGrid in which this column will be displayed // Utilize it to get DataGrid's clientID or to call PostBackLink function var $Row; // Contains the data of all the columns for this row. var $Width = NULL; // The Width in HTML units for this colums. Example: "50%", "150px", ... // constructor. Initializes this grid function DataGridColumn($field_name, $caption, $canSort = true, $canEdit = true) { $this->FieldName = $field_name; $this->Caption = $caption; $this->Value = ""; $this->CanSort = $canSort; $this->CanEdit = $canEdit; $this->CanShow = true; } // Renders the data of this column in normal mode function Render() { return $this->Value; } // Renders the data of this column in editable mode function RenderEdit() { return $this->Value; } // Renders the data of this column in editable mode function RenderFilter() { return $this->Value; } // Initizlize this column function Init($value, $row, $dataGrid) { $this->Value = $value; $this->Parent = $dataGrid; $this->Row = $row; } // Return value for this column. Used at the Insert and Update operations function GetValue() { return $this->Value; } // set value for this column. Used at the Insert and Update operations function SetValue($v) { $name = $this->Parent->clientID."_$this->FieldName"; $_POST[$name] = $v; $_POST[strtolower($name)] = $v; } // Return value for this column. Used at the Insert and Update operations function GetFilterValue() { $name = $this->Parent->clientID."_filter_$this->FieldName"; $retValue = ""; if (!$this->Parent->ClearAllFilters) $retValue = POST_PARAM($name); return $retValue; } } /*********************************************************************************************/ // Displays data of the Column as normal text, // but renders TextBox for editing or inserting class DataGridTextBoxColumn extends DataGridColumn { // Write the value to the cell function Render() { return "$this->Value"." "; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderEdit() { $name = $this->Parent->clientID."_$this->FieldName"; return "Value)."\" style='width: 100%; '>"; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderFilter() { $name = $this->Parent->clientID."_filter_$this->FieldName"; return "GetFilterValue())."\" style='width: 100%; '>"; } // return value to datagrid so that it could insert or update function GetValue() { $name = $this->Parent->clientID."_$this->FieldName"; $retValue = POST_PARAM($name); return $retValue; } } /*********************************************************************************************/ // Displays data of the Column as normal text, // but renders TextBox for editing or inserting class DataGridTriStateColumn extends DataGridColumn { // Write the value to the cell function Render() { if ($this->Value == 1) return ""; if ($this->Value == -1) return ""; if ($this->Value == 0) return ""; return "$this->Value"." "; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name // render drop down list which will allow users to choose an option function RenderEdit() { $retValue = ""; return $retValue; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderFilter() { $name = $this->Parent->clientID."_filter_$this->FieldName"; $retValue = ""; return $retValue; } // return value to datagrid so that it could insert or update function GetValue() { $name = $this->Parent->clientID."_$this->FieldName"; $retValue = POST_PARAM($name); return $retValue; } // Return value for this column. Used at the Insert and Update operations function GetFilterValue() { $retValue = ""; $name = $this->Parent->clientID."_filter_$this->FieldName"; if (!$this->Parent->ClearAllFilters) $retValue = POST_PARAM($name); if ($retValue == "ANY") $retValue=""; return $retValue; } } /*********************************************************************************************/ // Renders DropDownList for editing. This column contains several options. // It displays the text according to its options. class DataGridComboColumn extends DataGridColumn { // array of options of this drop down column var $options; // Construct a new combo box column function DataGridComboColumn($field_name, $caption, $canSort = true, $canEdit = true) { $this->FieldName = $field_name; $this->Caption = $caption; $this->Value = ""; $this->CanSort = $canSort; $this->CanEdit = $canEdit; $this->CanShow = true; $this->options = array(); } // add a new option for this column function AddOption ($key, $value) { $this->options[$key] = $value; } // search for key in options array which is equal to the value taht we should display. // then render value of array according to that key function Render() { return $this->options[$this->Value]." "; } // render drop down list which will allow users to choose an option function RenderEdit() { $retValue = ""; return $retValue; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderFilter() { $name = $this->Parent->clientID."_filter_$this->FieldName"; $retValue = ""; return $retValue; } // get the selected option. return it to datagrid to enable insert or update function GetValue() { $name = $this->Parent->clientID."_$this->FieldName"; $retValue = POST_PARAM($name); return $retValue; } } /*********************************************************************************************/ // This column generates checkbox field. Use this columns for int, bool and boolean types class DataGridCheckColumn extends DataGridColumn { var $text_yes, $text_no; function DataGridCheckColumn ($field, $caption, $text_yes = "True", $text_no="False") { $this->text_yes = $text_yes; $this->text_no = $text_no; $this->FieldName = $field; $this->Caption = $caption; $this->CanEdit = true; $this->CanShow = true; $this->CanSort = true; } function Render() { $text = $this->text_no; $checked = ""; if (isset ($this->Value) && ($this->Value==true || $this->Value==1)) { $checked = " checked "; $text = $this->text_yes; } return "$text"; } function RenderEdit() { $name = $this->Parent->clientID.$this->FieldName."chb[]"; $checked = ""; $text = $this->text_no; if (is_array ($this->Row)) { if (isset ($this->Value) && ($this->Value==true || $this->Value==1)) { $checked = " checked "; $text = $this->text_yes; } else { $text = $this->text_no; } } else $text = "$this->Caption"; // rendering for insert or for row which is initialized right before update return ""; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderFilter() { $name = $this->Parent->clientID."_filter_$this->FieldName"; return "GetFilterValue())."\" style='width: 100%; '>"; } function GetValue() { $name = $this->Parent->clientID.$this->FieldName."chb"; $c = POST_PARAM($name); return isset($c)?1:0; } } /*********************************************************************************************/ // This column renders any link that you like which in turn causes to call user defined function. // It replaces the <:link:> tag that of that template with appropriate post back link. // When this link is clicked this column calls the call back // function which has been provided when it is constructed. As the parameter it passes the // key field value of that row. function call occurs before render as other post back calls class DataGridCommandColumn extends DataGridColumn { var $Template; // the template that contains interface for this column. // This template must contain <:link:> tag to enable post back var $CommandName; // name for this command. helps to build post back javascript var $Callback; // the function name to be called when this link is clicked // constructs a new command column function DataGridCommandColumn($field_name, $caption, $template, $commandName, $callback) { $this->Template = $template; $this->CommandName = $commandName; $this->FieldName = $field_name; $this->Caption = $caption; $this->Value = ""; $this->CanSort = false; $this->CanEdit = false; $this->CanShow = true; $this->Callback = $callback; } // put the link into the template // render it to users function Render() { $this->Template->output = $this->Template->original; $this->Template->Put("link", $this->Parent->PostBackLink("$this->CommandName=$this->Value")); return $this->Template->output." "; } // command columns cannot be editable // if you need your own implementation derive from this class // and implement RenderEdit method function RenderEdit() { return "not implemented"; } // command columns cannot be editable // if you need your own implementation derive from this class // and implement RenderEdit method function RenderFilter() { return "not implemented"; } // Init the datagrid. function Init($value, $row, $dataGrid) { $this->Value = $value; $this->Parent = $dataGrid; $this->Row = $row; } // This won't ever be called. But anyway return its value not to cause to change any data function GetValue() { return $this->Value; } } /*********************************************************************************************/ // This is class is internally utilized by DataGrid to contain Toolbar Commands class DataGridToolbarCommand { var $template, $commandName, $callBackFunction; function DataGridToolbarCommand($cmdName, $tpl, $callBack) { $this->template = $tpl; $this->commandName = $cmdName; $this->callBackFunction = $callBack; } } // This class will render calendar to edit datetime field class DataGridCalendarColumn extends DataGridColumn { function DataGridCalendarColumn($field_name, $caption, $canSort = true, $canEdit = true) { $this->FieldName = $field_name; $this->Caption = $caption; $this->Value = ""; $this->CanSort = $canSort; $this->CanEdit = $canEdit; $this->CanShow = true; } // Renders the data of this column in normal mode function Render() { if ($this->Value == "0000-00-00 00:00:00") return " "; return date("d F Y", strtotime($this->Value)); } // Renders the data of this column in editable mode function RenderEdit() { $str = "\n"; $str .= "\n"; $str .= "\n"; #$str .= "\n"; $str .= "\n"; if (!IsClientScriptRegistered ("PHP_DataGrid_CalendarColumn_JSs")) { RegisterClientScript("PHP_DataGrid_CalendarColumn_JSs", NULL); } else $str = ""; $name = $this->Parent->clientID."_$this->FieldName"; $date = ($this->Value=="0000-00-00 00:00:00"||$this->Value==NULL)?"":date("Y-m-d", strtotime($this->Value)); $str .= ""; $str .= " \n"; $str .= ""; return $str; } // Render textbox to enable editing. As its name, put the // parents clientID + this columns field name function RenderFilter() { $name = $this->Parent->clientID."_filter_$this->FieldName"; return "GetFilterValue())."\" style='width: 100%; '>"; } // Initizlize this column function Init($value, $row, $dataGrid) { $this->Value = $value; $this->Parent = $dataGrid; $this->Row = $row; } // Return value for this column. Used at the Insert and Update operations function GetValue() { $name = $this->Parent->clientID."_$this->FieldName"; return POST_PARAM($name); } } /*********************************************************************************************/ // This class manages database operations for MySQL class DB { var $server = ""; var $login = ""; var $password = ""; var $database = ""; var $last_error = ""; var $last_sql; var $connection_link = NULL; function DB ($server=NULL, $user_name=NULL, $pwd=NULL, $db=NULL) { global $MYSQL_HOST, $MYSQL_USER, $MYSQL_PASSWORD, $MYSQL_DB; // assigning local variables if (!isset ($server)) $server = $MYSQL_HOST; $this->server = $server; if (!isset ($user_name)) $user_name = $MYSQL_USER; $this->login = $user_name; if (!isset ($pwd)) $pwd = $MYSQL_PASSWORD; $this->password = $pwd; if (!isset ($db)) $db = $MYSQL_DB; $this->database = $db; $this->last_error = ""; $this->last_sql = ""; } // connects to the server and returns the link identifier function Connect () { $this->connection_link = NULL; if (!$this->connection_link = mysql_connect($this->server, $this->login, $this->password)) { $this->last_error = mysql_error($this->connection_link); trigger_error("Could not connect to server: server: $this->server
user_name: $this->login
password: $this->password
Error: $this->last_error"); return false; } if (!mysql_select_db($this->database, $this->connection_link)) { $this->last_error = mysql_error($this->connection_link); trigger_error ("Could not select database: $this->database
Error: $this->last_error
"); return false; } return true; } // Executes a single sql on the database // if successfull, returns true, otherwise false; function Execute ($sql) { $result = $this->GetResult($sql); return isset ($result); } // executes the given query and returns a single value function GetScalar ($sql) { $result = $this->GetResult($sql); if ( ! isset($result)) return NULL; $row = mysql_fetch_array($result); return $row[0]; } // retrieves the data set based on the given query function GetResult ($sql) { if ( ! isset($this->connection_link)) if (! $this->Connect()) return NULL; $this->last_sql = $sql; $result = mysql_query($sql, $this->connection_link); if (!$result) { $this->last_error = mysql_error($this->connection_link); trigger_error ("DB Error, could not query the database
Error: $this->last_error
"); return NULL; } return $result; } } /*********************************************************************************************/ // This class manages the interface of data grid. But it can be used for your own purposes. // On the whole this class helps you to split PHP and HTML code. class Template { // holds the original template content and // is never changed by its functions var $original; // the generated output var $output; // name of tag. this field is only used when an // instance is acquired by Find() method var $tag_name; var $file_name; // constructs a new Template object. function Template() { $this->original = ""; $this->output = ""; $this->tag_name = ""; } // loads template content from file function LoadFile($file_name) { if (! file_exists($file_name)) { trigger_error ("Template::LoadFile() function could not find file $file_name."); return false; } $this->file_name = $file_name; $filename = $file_name; $this->original = ""; $this->output = ""; if (filesize($file_name) == 0) return true; $handle = fopen($file_name, "r"); $this->original = fread($handle, filesize($file_name)); $this->output = $this->original; fclose($handle); return true; } // sets the template content in memory and will work on it. // Utilize when not loading from file function SetContent($new_content) { $this->file_name = ""; $this->output = $new_content; $this->original = $new_content; } function Clear() { $this->output = ""; } function Restore() // resets to original { $this->output = $this->original; } // Finds the text prefixed by the given text // and replaces with the provided value function Put($tag_name, $value) { if ( ! eregi ("^[a-z|A-Z|0-9|_]+$", $tag_name)) { trigger_error ("Ivalid parameter passed to Template::Put( ). tag_name is \"$tag_name\""); return false; } //$this->output = eregi_replace ("{+$tag_name}+", $value, $this->output); $this->output = eregi_replace ("<:$tag_name:>", $value, $this->output); return true; } // finds a group to repeated, creates a new instance of Template // with initialized and ready to use fields, and returns it. // Work on it using Repeat and Put methods and at the end // call its parent's Apply method passing this instance as the parameter function Find($tag_name) { if ( ! eregi ("^[a-z|A-Z|0-9|_]+$", $tag_name)) { trigger_error ("Ivalid parameter passed to Template::Put( ). tag_name is \"$tag_name\""); return NULL; } $regex = "<$tag_name:begin>.+<$tag_name:end>"; if (eregi ($regex, $this->output, $regs)) { $regs[0] = eregi_replace ("<$tag_name:begin>|<$tag_name:end>","", $regs[0]); // building a block to retrieve $retValue = new Template(); $retValue->tag_name = $tag_name; $retValue->file_name = $this->file_name; $retValue->original = $regs[0]; $retValue->output = $regs[0]; return $retValue; } else return NULL; } // Appends the original to the end of output. // Use Put and repeat methods to set values to new tags function Repeat() { $this->output .= $this->original; } // applies the child template to this instance // see Find() method function Apply($template) { /*if ( ! ($template instanceof Template) ) { trigger_error("Template::Apply method acquires only Template instances"); return false; }*/ $tag_name = $template->tag_name; $regex = "<$tag_name:begin>.+<$tag_name:end>"; $this->output = eregi_replace ($regex, $template->output, $this->output); return true; } // Renders the output // perform any prerender operations here function Render($remove_left_tags = false) { if ($remove_left_tags) $this->RemoveLeftTags(); echo "$this->output"; } // Prepares the content for output. // it will remove all the forgotten tags // and return the HTML output function RemoveLeftTags() { $regex = "<:([a-z|A-Z|0-9|_ ]+)*:>|<([a-z|A-Z|0-9|_ ]+):begin>.*<([a-z|A-Z|0-9|_ ]+):end>"; $this->output = eregi_replace($regex, "", $this->output); } } /*********************************************************************************************/ // GLOBAL FUNCTIONS. This helps data grid to get work properly $scripts = Array(); function RegisterClientScript($key, $value) { global $scripts; $scripts[] = strtolower($key); if ( isset ($value)) echo ("$value"); } function IsClientScriptRegistered($key) { global $scripts; for ($i=0; $i