Now it's time to combine the previous two topic(topic1, topic2) together and write a PHP code that gets a file's total page number.
First we must find the file's mime type. And as i explained in this topic, we use fileinfo or file command from Linux console to get the mime type of the file like;
if(function_exists('finfo_file')){
$finfo = finfo_open(FILEINFO_MIME);
$file_type = finfo_file($finfo, $file);
finfo_close($finfo);
}else{
echo "Pecl Fileinfo package not found!!! Trying to get file mime type from Linux Console\r\n";
$file_type = trim(exec("file -bi " . escapeshellarg($file)));
}
if(stripos($file_type, "\\012- ") !== false)
$file_type = substr($file_type, stripos($file_type, "\\012- ")+6, strlen($file_type));
Then we coupled the file's mime type from our predefined mime types;
//Our predefined mime types
var $image_formats = array("image/jpeg", "image/gif", "image/bmp");
var $file_formats = array("application/octet-stream", "application/vnd.ms-excel", "application/msword", "application/vnd.ms-powerpoint", "text/plain", "application/rtf", "text/html");
//check to know which function we use to convert the file to pdf
if(in_array($file_type, $this->image_formats)){
$file = $this->imageProcessing($file);
}else if(in_array($file_type, $this->file_formats)){
$file = $this->fileProcessing($file);
}
In imageProcessing function we convert the image files like jpegs, gifs, bmps to pdfs as i explained in this topic like;
private function imageProcessing($file){
$file_allinfo = pathinfo($file);
$file_pdf = $file_allinfo['dirname'] . "/" . $file_allinfo['filename'] . "_converted.pdf";
exec('convert ' . $file . " " . $file_pdf);
return $file_pdf;
}
and in fileProcessing function we convert the Microsoft Office files or html files etc to pdfs as i explained in this topic like;
private function fileProcessing($file){
$file_allinfo = pathinfo($file);
$file_pdf = $file_allinfo['dirname'] . "/" . $file_allinfo['filename'] . "_converted.pdf";
exec('python ./DocumentConverter.py ' . $file . " " . $file_pdf);
return $file_pdf;
}
But in order to run the function above, we mustn't forget to run OpenOffice at port 80 as i explained before;
openoffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless &
And the last part that gets the total page number info and deletes the pdf file;
//this $file variable contains the path of pdf file that i return from one of my function
$file_allinfo = pathinfo($file);
$file_path_and_name = $file_allinfo['dirname'] . "/" . $file_allinfo['filename'];
exec("pdfinfo ". $file . " | grep Pages: | awk '{print $2}' | tail -n1", $output ,$retval);
$total_page_count = str_replace(" ", "", $output[0]);
unlink($file) or die("Unable To Delete Created File!\r\n");
I write this example as a PHP class, if you want to use it just create an object and pass it's function the file's path like;
require ('PageCount.php');
$c_pagecount = new page_count_class();
$v_totalpage = $c_pagecount->pageCounting("./sample.doc");
var_dump($v_totalpage);
Here you can get some sample files, with sample test code and my class file.
November 22, 2008
Linux Get All Types Of Files Total Page Numbers (Almost All Types)
In order to get the total page of a document which is to be faxed or mailed, you can use OpenOffice export tools, imagemagick and some Linux console commands together.
It is easy to get total page numbers of files by converting all files to pdf and use Linux's 'pdfinfo' console command. But it isn't easy to convert all files to pdf, especially the Microsoft Office ones. In order to convert Microsoft Office documents, you must have OpenOffice in your system. And you must run OpenOffice at background by this command;
openoffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless &
Then with this code that i found from here, you can convert excel, word, powerpoint, rtf, txt, html files to pdf files over OpenOffice with Python from Linux Console like;
python ./DocumentConverter.py sample.doc sample.pdf
In order to run the code above you must first run OpenOffice as i mentioned before.
Also if you need to convert image files to pdf files and want to get their total page numbers, you can use imagemagick's convert command from Linux console;
convert sample.jpg sample.pdf
After converting the files to pdfs, you can get the total page of file by;
pdfinfo sample.pdf | grep "Pages:" | awk '{print $2}' | tail -n1
It is easy to get total page numbers of files by converting all files to pdf and use Linux's 'pdfinfo' console command. But it isn't easy to convert all files to pdf, especially the Microsoft Office ones. In order to convert Microsoft Office documents, you must have OpenOffice in your system. And you must run OpenOffice at background by this command;
openoffice "-accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager" -norestore -nofirststartwizard -nologo -headless &
Then with this code that i found from here, you can convert excel, word, powerpoint, rtf, txt, html files to pdf files over OpenOffice with Python from Linux Console like;
python ./DocumentConverter.py sample.doc sample.pdf
In order to run the code above you must first run OpenOffice as i mentioned before.
Also if you need to convert image files to pdf files and want to get their total page numbers, you can use imagemagick's convert command from Linux console;
convert sample.jpg sample.pdf
After converting the files to pdfs, you can get the total page of file by;
pdfinfo sample.pdf | grep "Pages:" | awk '{print $2}' | tail -n1
November 21, 2008
PHP-Pecl FileInfo Package Installation Ubuntu
To get a file's mime type within a php code, you can use mime_content_type(), but it is deprecated. So instead of it you can use Pecl/FileInfo package. In order to install FileInfo package to your Ubuntu system, you need to install these packages first (i assume you already have apache2, php5, libapache2-mod-php5 etc);
build-essential (this gets rid of => C compiler cannot create executables)
php5-dev (this gets rid of => sh: phpize: command not found)
php5-pear
libmagic-dev (this gets rid of =>
checking for magic files in default path... not found
configure: error: Please reinstall the libmagic distribution
ERROR: `/tmp/pear/cache/Fileinfo-1.0.4/configure' failed)
libmagic1
Then you do as root;
pear channel-update pear.php.net
pecl install Fileinfo
Then within your php.ini files (/etc/php5/apache2/php.ini and /etc/php5/cli/php.ini), you add this line;
extension=fileinfo.so
And lastly as root we will copy these files;
cp /usr/share/file/magic.mime /etc/magic
cp /usr/share/file/magic.mime /etc/magic.mime
Start the apache server and you are ready to go;
/etc/init.d/apache2 restart
And here is the php code to get file's mime type;
$finfo = finfo_open(FILEINFO_MIME);
$mime_type = finfo_file($finfo, $file_path);
finfo_close($finfo);
build-essential (this gets rid of => C compiler cannot create executables)
php5-dev (this gets rid of => sh: phpize: command not found)
php5-pear
libmagic-dev (this gets rid of =>
checking for magic files in default path... not found
configure: error: Please reinstall the libmagic distribution
ERROR: `/tmp/pear/cache/Fileinfo-1.0.4/configure' failed)
libmagic1
Then you do as root;
pear channel-update pear.php.net
pecl install Fileinfo
Then within your php.ini files (/etc/php5/apache2/php.ini and /etc/php5/cli/php.ini), you add this line;
extension=fileinfo.so
And lastly as root we will copy these files;
cp /usr/share/file/magic.mime /etc/magic
cp /usr/share/file/magic.mime /etc/magic.mime
Start the apache server and you are ready to go;
/etc/init.d/apache2 restart
And here is the php code to get file's mime type;
$finfo = finfo_open(FILEINFO_MIME);
$mime_type = finfo_file($finfo, $file_path);
finfo_close($finfo);
C compiler cannot create executables
C compiler cannot create executables
If you are facing with this error while compiling some packages in ubuntu, just do;
aptitude install build-essential
If you are facing with this error while compiling some packages in ubuntu, just do;
aptitude install build-essential
/usr/bin/ld: crt1.o: No such file: No such file or directory collect2: ld returned 1 exit status
/usr/bin/ld: crt1.o: No such file: No such file or directory
collect2: ld returned 1 exit status
If you are using ubuntu and faced with an error message like this while compiling your c code, just install libc6-dev package.
sudo aptitude install libc6-dev
collect2: ld returned 1 exit status
If you are using ubuntu and faced with an error message like this while compiling your c code, just install libc6-dev package.
sudo aptitude install libc6-dev
November 18, 2008
Unknown Role class: PEAR_Installer_Role_Pear_Installer_role_test
If you ever faced with this problem(Unknown Role class: PEAR_Installer_Role_Pear_Installer_role_test) while installing some pear package like OLE, just do;
export LC_ALL="C"
export LANG="C"
pear install OLE
also this command may not work then use;
pear install channel://pear.php.net/OLE-1.0.0RC1
and also if you ever faced with this while compiling PHP;
Fatal error: Call to undefined method PEAR_Registry::packageinfo() in phar://install-pear-nozlib.phar/PEAR/Dependency2.php on line 659
make[1]: *** [install-pear-installer] Error 255
make : *** [install-pear] Error 2
the same solution above is worked too;
export LC_ALL="C"
export LANG="C"
make install
export LC_ALL="C"
export LANG="C"
pear install OLE
also this command may not work then use;
pear install channel://pear.php.net/OLE-1.0.0RC1
and also if you ever faced with this while compiling PHP;
Fatal error: Call to undefined method PEAR_Registry::packageinfo() in phar://install-pear-nozlib.phar/PEAR/Dependency2.php on line 659
make[1]: *** [install-pear-installer] Error 255
make : *** [install-pear] Error 2
the same solution above is worked too;
export LC_ALL="C"
export LANG="C"
make install
Just A Little Warning About PhpExcelWriter
I wrote how to get rid of UTF-8 character encoding problem while reading Excel files with PhpExcelReader. Now i want to warn you about numerics in PhpExcelWriter. For example when i write an 11 character word or a bigger one to the Excel file;
902321111111
it is always showed in excel file;
9,02321E+11
If you faced a problem like it, just write this value to the excel file not by write function;
$workSheet->write(0, 0, $value);
write it by writeString function;
$workSheet->writeString(0, 0, $value);
So the whole code seems like;
require_once("Spreadsheet/Excel/Writer.php");
$workbook = & new Spreadsheet_Excel_Writer();
$workbook->send('excel.xls');
$workbook->setVersion(8);
$worksheet = & $workbook->addWorksheet('Sheet1');
$worksheet->setInputEncoding('UTF-8');
$workSheet->writeString(0, 0, "902321111111");
$workbook->close();
902321111111
it is always showed in excel file;
9,02321E+11
If you faced a problem like it, just write this value to the excel file not by write function;
$workSheet->write(0, 0, $value);
write it by writeString function;
$workSheet->writeString(0, 0, $value);
So the whole code seems like;
require_once("Spreadsheet/Excel/Writer.php");
$workbook = & new Spreadsheet_Excel_Writer();
$workbook->send('excel.xls');
$workbook->setVersion(8);
$worksheet = & $workbook->addWorksheet('Sheet1');
$worksheet->setInputEncoding('UTF-8');
$workSheet->writeString(0, 0, "902321111111");
$workbook->close();
PhpExcelReader UTF-8 Problem HOW TO
At one of my works i had to read Excel files and write their contents to database for a Turkish company. The site's encoding is UTF-8 and the table's encoding is described as 'utf8_turkish_ci'.
I used the PhpExcelReader to read Excel files and i wrote down this code from their examples;
require_once('Excel/reader.php');
$data = new Spreadsheet_Excel_reader();
$data->setOutputEncoding('UTF-8');
$data->read($file_path);
but always when PhpExcelReader saw a Turkish character it stopped reading. So i decided that there may be an encoding mistake, so first i changed the 'outputEncoding's value. But it didn't change anything, also vitiated the words spellings. So i put another encoding conversion while it was reading the Excel files content.
for ($i = 2, $j = 0; $i <= $data->sheets[0]['numRows']; $i++, $j++) {
$value = mb_convert_encoding($data->sheets[0]['cells'][$i][$value_row], "UTF-8", "ISO-8859-9");
}
So that's it. After putting these conversions the contents are saved straightly. Also here is a good trick for ya;
After the excel file is uploaded to the system check all the first rows and ask user to couple them with your database rows from dropdown lists. After user couples the excel rows with database rows, go start from the 2nd row of excel file to read, and save the selected rows to database rows and then get 3rd and 4th etc. So you not need to enforce the user to obey your standarts.
I used the PhpExcelReader to read Excel files and i wrote down this code from their examples;
require_once('Excel/reader.php');
$data = new Spreadsheet_Excel_reader();
$data->setOutputEncoding('UTF-8');
$data->read($file_path);
but always when PhpExcelReader saw a Turkish character it stopped reading. So i decided that there may be an encoding mistake, so first i changed the 'outputEncoding's value. But it didn't change anything, also vitiated the words spellings. So i put another encoding conversion while it was reading the Excel files content.
for ($i = 2, $j = 0; $i <= $data->sheets[0]['numRows']; $i++, $j++) {
$value = mb_convert_encoding($data->sheets[0]['cells'][$i][$value_row], "UTF-8", "ISO-8859-9");
}
So that's it. After putting these conversions the contents are saved straightly. Also here is a good trick for ya;
After the excel file is uploaded to the system check all the first rows and ask user to couple them with your database rows from dropdown lists. After user couples the excel rows with database rows, go start from the 2nd row of excel file to read, and save the selected rows to database rows and then get 3rd and 4th etc. So you not need to enforce the user to obey your standarts.
Prado PHP Framework HOW TO 5 - TDataGrid with TDropDownList, TCheckBox
One of the good component's of Prado is it's DataGrid. But i must admit, it refreshes the page so much. In this point you'll understand how javascript is good. But for the one's who dealed with the same problem that how to use TCheckBox or TDropDownList in TDataGrid, i want to explain how i overcome it in here, not how javascript is better.
In here i use basics of TDataGrid if you want to see more about TDataGrid, you can look here.
Also to use this example i define a database schema named as 'test' and username and password also named as 'test'. Then i define 2 tables in my schema, one for items and one for types. Items have type_id's as one of their row. So we can get the values from two tables at the same time while using drop down column in our data grid. I also include the sql file to the source code.
First we define our data grid component;
<com:TDataGrid
ID="DataGrid"
DataKeyField="ID"
AutoGenerateColumns="false"
OnItemCreated="itemCreated"
OnEditCommand="editItem"
OnUpdateCommand="saveItem"
OnDeleteCommand="deleteItem"
OnCancelCommand="cancelItem"
>
Then we define our components that'll be in our data grid;
----------------------------The checkbox--------------------------------
<com:TTemplateColumn ID="checkbox_column">
<prop:ItemTemplate>
<com:TCheckBox ID="select" />
<com:THiddenField ID="item_id" />
</prop:ItemTemplate>
</com:TTemplateColumn>
-------------------------------Edit Column-------------------------------
<com:TEditCommandColumn
UpdateText="Save"
EditText="Edit"
CancelText="Cancel"
/>
------------------------------Drop Down List Column--------------------
<com:TDropDownListColumn
ID="dropdown_column"
DataTextField="type_name"
ListDataSource=<%= $this->LoadDropDown() %>
ListValueField="type_id"
/>
------------------------------Text Box Column----------------------------
<com:TBoundColumn
ID="textbox_column"
DataField="item_name"
/>
------------------------------Delete Column-------------------------------
<com:TButtonColumn
ID="delete_column"
Text="Delete"
CommandName="delete"
/>
At the end we close the data grid component's tag.
</com:TDataGrid>
And we define a button to delete the selected one's.
<com:TButton ID="delete_selecteds"
Text="Delete Selecteds"
onClick="DeleteSelecteds"
/>
And we mustn't forget to enclose our TDataGrid and TButton in TForm component. Now our html page is ready, so get going to write the php page.
We define a local variable to populate our data grid everytime and onLoad function first;
private $_data=null;
public function onLoad($param){
parent::onLoad($param);
if(!$this->IsPostBack){
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
}
We bind the data we have, to our data grid, above. Then comes our second function that creates a TList component and populates our drop down list column in our data grid with it;
public function LoadDropDown(){
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query = "SELECT * FROM types";
$command = $db_connection->createCommand($sql_query);
$db_records = $command->query();
$data=new TList; $i=0;
foreach($db_records as $key)
$data->add(array('type_id'=>$key["type_name"]));
$db_connection->active = false;
return $data;
}
After that we started to define our public functions that are called by our data grid component when a delete, update, save or cancel command comes;
public function itemCreated($sender,$param){
$item=$param->Item;
if($item->ItemType==='EditItem'){
$item->textbox_column->TextBox->Columns=10;
}
if($item->ItemType==='Item' || $item->ItemType==='AlternatingItem' || $item->ItemType==='EditItem'){
$item->delete_column->Button->Attributes->onclick='if(!confirm(\'Are you sure?\')) return false;';
}
}
This function above, provides a confirm box to our delete buttons to check if person is sure to delete the item.
public function editItem($sender,$param){
$this->DataGrid->EditItemIndex=$param->Item->ItemIndex;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
With this function above, we open the text boxes, drop down lists instead of the items. So user can edit them.
public function saveItem($sender,$param){
$item=$param->Item;
if($this->_data===null)
$this->loadData();
$updateRow=null;
foreach($this->_data as $index=>$row)
if($row['ID']===$this->DataGrid->DataKeys[$item->ItemIndex])
$updateRow=&$this->_data[$index];
if($updateRow!==null){
$old_typename = $updateRow['type_name'];
$old_itemname = $updateRow['item_name'];
}
$new_typename = $item->dropdown_column->DropDownList->SelectedValue;
$new_itemname = $item->textbox_column->TextBox->Text;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$transaction = $db_connection->beginTransaction();
try{
$sql_query = "Select type_id from types where type_name='". $new_typename ."'";
$command = $db_connection->createCommand($sql_query);
$new_typeid = $command->queryScalar();
$sql_query = "Select type_id from types where type_name='". $old_typename ."'";
$command = $db_connection->createCommand($sql_query);
$old_typeid = $command->queryScalar();
$sql_query = "Select item_id from items where item_type='" . $old_typeid . "' and item_name='". $old_itemname
."'";
$command = $db_connection->createCommand($sql_query);
$item_id = $command->queryScalar();
$sql_query = "update items set item_name='". $new_itemname ."', item_type='". $new_typeid ."' where item_id='
". $item_id ."'";
$command = $db_connection->createCommand($sql_query);
$command->execute();
$transaction->commit();
}catch(Exception $ex){
$transaction->rollback();
var_dump("UPPSSS Update Failed");
return;
}
$this->updateGrid(
$this->DataGrid->DataKeys[$item->ItemIndex],
$new_typename,
$new_itemname
);
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
$db_connection->Active = false;
}
With this function above, if user clicks the save button in edit mode, we first find the old values of the item and then find the item's id. Then we get the new values of the item from text box and drop down list and update the item with them.
public function cancelItem($sender,$param){
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
With this function above, if user clicks the cancel button in edit mode, we do nothing and refresh the list.
public function deleteItem($sender,$param){
$this->deleteFromGrid($this->DataGrid->DataKeys[$param->Item->ItemIndex]);
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
$this->response->reload();
}
With this function above, if user clicks the delete button we delete the item at this index.
public function deleteSelecteds(){
foreach($this->DataGrid->Items as $i){
if($i->checkbox_column->select->Checked)
$this->deleteFromGrid($this->DataGrid->DataKeys[$i->ItemIndex]);
}
$this->response->reload();
}
With this function above, if user clicks our 'Delete Selecteds' button we walk through the indexes whom their checkbox's clicked and delete them one by one.
Other functions are implementation details, that's why they defined as 'protected';
protected function getData(){
if($this->_data===null)
$this->loadData();
return $this->_data;
}
protected function loadData(){
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query= "SELECT item_id, item_name, item_type FROM items";
$command = $db_connection->createCommand($sql_query);
$db_records = $command->query(); $i = 0;
foreach($db_records as $key){
$sql_query = "SELECT type_name FROM types where type_id='" . $key["item_type"] . "'";
$command = $db_connection->createCommand($sql_query);
$type_name = $command->queryScalar();
$array[$i] = array(
'ID'=>$i+1,
'type_name'=>$type_name,
'item_name'=>$key["item_name"],
);
$i++;
}
$this->_data = $array;
$this->saveData();
$db_connection->active = false;
}
With this function above we populate our datagrid from our mysql server.
protected function saveData(){
$this->setViewState('Data',$this->_data);
}
protected function updateGrid($id, $type_name, $item_name){
if($this->_data===null)
$this->loadData();
$updateRow=null;
foreach($this->_data as $index=>$row)
if($row['ID']===$id)
$updateRow=&$this->_data[$index];
if($updateRow!==null){
$updateRow['type_name']=$type_name;
$updateRow['item_name']=$item_name;
$this->saveData();
}
}
With this function above we update the values of the item that is at that index.
protected function deleteFromGrid($id){
if($this->_data===null)
$this->loadData();
$deleteIndex=-1;
foreach($this->_data as $index=>$row)
if($row['ID']===$id){
$deleteIndex=$index;
$deleteRow = &$this->_data[$index];
}
if($deleteIndex>=0){
unset($this->_data[$deleteIndex]);
if($deleteRow!==null){
$old_typename = $deleteRow['type_name'];
$old_itemname = $deleteRow['item_name'];
}
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query = "Select type_id from types where type_name='" . $old_typename . "'";
$command = $db_connection->createCommand($sql_query);
$type_id = $command->queryScalar();
$transaction = $db_connection->BeginTransaction();
try{
$sql_query = "delete from items where item_name='". $old_itemname ."' and item_type='". $type_id ."'"
;
$command = $db_connection->createCommand($sql_query);
$command->execute();
$transaction->commit();
}catch(Exception $ex){
$transaction->rollBack();
var_dump("UPPSSS Delete Failed");
return;
}
$this->saveData();
$db_connection->Active = false;
}
With this function above we delete the item that is at that index.
Here is the source code with the mysql dump of the database we used in the example. Also to run the application you need to copy Prado's directory to the same place with the datagrid directory.
In here i use basics of TDataGrid if you want to see more about TDataGrid, you can look here.
Also to use this example i define a database schema named as 'test' and username and password also named as 'test'. Then i define 2 tables in my schema, one for items and one for types. Items have type_id's as one of their row. So we can get the values from two tables at the same time while using drop down column in our data grid. I also include the sql file to the source code.
First we define our data grid component;
<com:TDataGrid
ID="DataGrid"
DataKeyField="ID"
AutoGenerateColumns="false"
OnItemCreated="itemCreated"
OnEditCommand="editItem"
OnUpdateCommand="saveItem"
OnDeleteCommand="deleteItem"
OnCancelCommand="cancelItem"
>
Then we define our components that'll be in our data grid;
----------------------------The checkbox--------------------------------
<com:TTemplateColumn ID="checkbox_column">
<prop:ItemTemplate>
<com:TCheckBox ID="select" />
<com:THiddenField ID="item_id" />
</prop:ItemTemplate>
</com:TTemplateColumn>
-------------------------------Edit Column-------------------------------
<com:TEditCommandColumn
UpdateText="Save"
EditText="Edit"
CancelText="Cancel"
/>
------------------------------Drop Down List Column--------------------
<com:TDropDownListColumn
ID="dropdown_column"
DataTextField="type_name"
ListDataSource=<%= $this->LoadDropDown() %>
ListValueField="type_id"
/>
------------------------------Text Box Column----------------------------
<com:TBoundColumn
ID="textbox_column"
DataField="item_name"
/>
------------------------------Delete Column-------------------------------
<com:TButtonColumn
ID="delete_column"
Text="Delete"
CommandName="delete"
/>
At the end we close the data grid component's tag.
</com:TDataGrid>
And we define a button to delete the selected one's.
<com:TButton ID="delete_selecteds"
Text="Delete Selecteds"
onClick="DeleteSelecteds"
/>
And we mustn't forget to enclose our TDataGrid and TButton in TForm component. Now our html page is ready, so get going to write the php page.
We define a local variable to populate our data grid everytime and onLoad function first;
private $_data=null;
public function onLoad($param){
parent::onLoad($param);
if(!$this->IsPostBack){
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
}
We bind the data we have, to our data grid, above. Then comes our second function that creates a TList component and populates our drop down list column in our data grid with it;
public function LoadDropDown(){
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query = "SELECT * FROM types";
$command = $db_connection->createCommand($sql_query);
$db_records = $command->query();
$data=new TList; $i=0;
foreach($db_records as $key)
$data->add(array('type_id'=>$key["type_name"]));
$db_connection->active = false;
return $data;
}
After that we started to define our public functions that are called by our data grid component when a delete, update, save or cancel command comes;
public function itemCreated($sender,$param){
$item=$param->Item;
if($item->ItemType==='EditItem'){
$item->textbox_column->TextBox->Columns=10;
}
if($item->ItemType==='Item' || $item->ItemType==='AlternatingItem' || $item->ItemType==='EditItem'){
$item->delete_column->Button->Attributes->onclick='if(!confirm(\'Are you sure?\')) return false;';
}
}
This function above, provides a confirm box to our delete buttons to check if person is sure to delete the item.
public function editItem($sender,$param){
$this->DataGrid->EditItemIndex=$param->Item->ItemIndex;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
With this function above, we open the text boxes, drop down lists instead of the items. So user can edit them.
public function saveItem($sender,$param){
$item=$param->Item;
if($this->_data===null)
$this->loadData();
$updateRow=null;
foreach($this->_data as $index=>$row)
if($row['ID']===$this->DataGrid->DataKeys[$item->ItemIndex])
$updateRow=&$this->_data[$index];
if($updateRow!==null){
$old_typename = $updateRow['type_name'];
$old_itemname = $updateRow['item_name'];
}
$new_typename = $item->dropdown_column->DropDownList->SelectedValue;
$new_itemname = $item->textbox_column->TextBox->Text;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$transaction = $db_connection->beginTransaction();
try{
$sql_query = "Select type_id from types where type_name='". $new_typename ."'";
$command = $db_connection->createCommand($sql_query);
$new_typeid = $command->queryScalar();
$sql_query = "Select type_id from types where type_name='". $old_typename ."'";
$command = $db_connection->createCommand($sql_query);
$old_typeid = $command->queryScalar();
$sql_query = "Select item_id from items where item_type='" . $old_typeid . "' and item_name='". $old_itemname
."'";
$command = $db_connection->createCommand($sql_query);
$item_id = $command->queryScalar();
$sql_query = "update items set item_name='". $new_itemname ."', item_type='". $new_typeid ."' where item_id='
". $item_id ."'";
$command = $db_connection->createCommand($sql_query);
$command->execute();
$transaction->commit();
}catch(Exception $ex){
$transaction->rollback();
var_dump("UPPSSS Update Failed");
return;
}
$this->updateGrid(
$this->DataGrid->DataKeys[$item->ItemIndex],
$new_typename,
$new_itemname
);
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
$db_connection->Active = false;
}
With this function above, if user clicks the save button in edit mode, we first find the old values of the item and then find the item's id. Then we get the new values of the item from text box and drop down list and update the item with them.
public function cancelItem($sender,$param){
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
}
With this function above, if user clicks the cancel button in edit mode, we do nothing and refresh the list.
public function deleteItem($sender,$param){
$this->deleteFromGrid($this->DataGrid->DataKeys[$param->Item->ItemIndex]);
$this->DataGrid->EditItemIndex=-1;
$this->DataGrid->DataSource=$this->Data;
$this->DataGrid->dataBind();
$this->response->reload();
}
With this function above, if user clicks the delete button we delete the item at this index.
public function deleteSelecteds(){
foreach($this->DataGrid->Items as $i){
if($i->checkbox_column->select->Checked)
$this->deleteFromGrid($this->DataGrid->DataKeys[$i->ItemIndex]);
}
$this->response->reload();
}
With this function above, if user clicks our 'Delete Selecteds' button we walk through the indexes whom their checkbox's clicked and delete them one by one.
Other functions are implementation details, that's why they defined as 'protected';
protected function getData(){
if($this->_data===null)
$this->loadData();
return $this->_data;
}
protected function loadData(){
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query= "SELECT item_id, item_name, item_type FROM items";
$command = $db_connection->createCommand($sql_query);
$db_records = $command->query(); $i = 0;
foreach($db_records as $key){
$sql_query = "SELECT type_name FROM types where type_id='" . $key["item_type"] . "'";
$command = $db_connection->createCommand($sql_query);
$type_name = $command->queryScalar();
$array[$i] = array(
'ID'=>$i+1,
'type_name'=>$type_name,
'item_name'=>$key["item_name"],
);
$i++;
}
$this->_data = $array;
$this->saveData();
$db_connection->active = false;
}
With this function above we populate our datagrid from our mysql server.
protected function saveData(){
$this->setViewState('Data',$this->_data);
}
protected function updateGrid($id, $type_name, $item_name){
if($this->_data===null)
$this->loadData();
$updateRow=null;
foreach($this->_data as $index=>$row)
if($row['ID']===$id)
$updateRow=&$this->_data[$index];
if($updateRow!==null){
$updateRow['type_name']=$type_name;
$updateRow['item_name']=$item_name;
$this->saveData();
}
}
With this function above we update the values of the item that is at that index.
protected function deleteFromGrid($id){
if($this->_data===null)
$this->loadData();
$deleteIndex=-1;
foreach($this->_data as $index=>$row)
if($row['ID']===$id){
$deleteIndex=$index;
$deleteRow = &$this->_data[$index];
}
if($deleteIndex>=0){
unset($this->_data[$deleteIndex]);
if($deleteRow!==null){
$old_typename = $deleteRow['type_name'];
$old_itemname = $deleteRow['item_name'];
}
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
$sql_query = "Select type_id from types where type_name='" . $old_typename . "'";
$command = $db_connection->createCommand($sql_query);
$type_id = $command->queryScalar();
$transaction = $db_connection->BeginTransaction();
try{
$sql_query = "delete from items where item_name='". $old_itemname ."' and item_type='". $type_id ."'"
;
$command = $db_connection->createCommand($sql_query);
$command->execute();
$transaction->commit();
}catch(Exception $ex){
$transaction->rollBack();
var_dump("UPPSSS Delete Failed");
return;
}
$this->saveData();
$db_connection->Active = false;
}
With this function above we delete the item that is at that index.
Here is the source code with the mysql dump of the database we used in the example. Also to run the application you need to copy Prado's directory to the same place with the datagrid directory.
Prado PHP Framework HOW TO 4 - MYSQL Everything (Almost)
In order to connect to a mysql server within your Prado application, first you need to define your Connection String in your application.xml file;
<module id="dbconnection" class="System.Data.TDataSourceConfig">
<database ConnectionString="mysql:host=YOURHOST;dbname=DBTOCONNECT" Username="YOURUSERNAME" Password="YOURPASSWORD" />
</module>
Then when you want to connect to your mysql server within one of your php file's, you just use this connection string;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
Then you are ready to go, first we preapare our query;
$sql_query = "";
$command = $connection->createCommand($sql);
Then run it as what it is;
------For select queries
$db_records = $command->query();
------For insert, update, delete queries
$command->execute();
After select queries, you can get the results by;
foreach($db_records as $key){
$key["row_name"];
}
And also if you are using InnoDB as your storage engine, you can use transactions and rollback from the states that throws exceptions. It's possible for MyISAM too but you must write down your own implementation that follows the running queries and when the time comes rollback them. Because when i searched for if MyISAM'll support transactions, i found that the programmers won't think anything about it because they developed them as they are, for higher speed and light applications MyISAM and for secured business applications InnoDB. If you want to look more for differences, you can look here. And here is how you can use transactions within your PHP code in Prado;
First we enclose our sql queries within try-catch block;
try{
}catch(Exception $ex){
}
Then after creating our connection object, we start transaction on it;
$transaction = $db_connection->beginTransaction();
At the end if some of our code fails and throws an exception, we rollback the operations in our catch block;
$transaction->rollBack();
And of course to close the connection;
$db_connection->Active = false;
Then our code now looks like;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
try{
$transaction = $db_connection->beginTransaction();
$sql_query = "";
$command = $connection->createCommand($sql);
$command->execute();
}catch(Exception $ex){
$transaction->rollBack();
}
$db_connection->Active = false;
Also you can enclose these code to another try catch block. It is good to see an Error Message instead of a whole Php-Prado Exception for our user's sake i think :)
<module id="dbconnection" class="System.Data.TDataSourceConfig">
<database ConnectionString="mysql:host=YOURHOST;dbname=DBTOCONNECT" Username="YOURUSERNAME" Password="YOURPASSWORD" />
</module>
Then when you want to connect to your mysql server within one of your php file's, you just use this connection string;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
Then you are ready to go, first we preapare our query;
$sql_query = "";
$command = $connection->createCommand($sql);
Then run it as what it is;
------For select queries
$db_records = $command->query();
------For insert, update, delete queries
$command->execute();
After select queries, you can get the results by;
foreach($db_records as $key){
$key["row_name"];
}
And also if you are using InnoDB as your storage engine, you can use transactions and rollback from the states that throws exceptions. It's possible for MyISAM too but you must write down your own implementation that follows the running queries and when the time comes rollback them. Because when i searched for if MyISAM'll support transactions, i found that the programmers won't think anything about it because they developed them as they are, for higher speed and light applications MyISAM and for secured business applications InnoDB. If you want to look more for differences, you can look here. And here is how you can use transactions within your PHP code in Prado;
First we enclose our sql queries within try-catch block;
try{
}catch(Exception $ex){
}
Then after creating our connection object, we start transaction on it;
$transaction = $db_connection->beginTransaction();
At the end if some of our code fails and throws an exception, we rollback the operations in our catch block;
$transaction->rollBack();
And of course to close the connection;
$db_connection->Active = false;
Then our code now looks like;
$db_connection = $this->Application->Modules['dbconnection']->Database;
$db_connection->Active = true;
try{
$transaction = $db_connection->beginTransaction();
$sql_query = "";
$command = $connection->createCommand($sql);
$command->execute();
}catch(Exception $ex){
$transaction->rollBack();
}
$db_connection->Active = false;
Also you can enclose these code to another try catch block. It is good to see an Error Message instead of a whole Php-Prado Exception for our user's sake i think :)
Subscribe to:
Comments (Atom)
.bmp)