FG Soft

Development Blog

Upload file using Zend Framework

Uploading a file using Zend Framework is really easy and requires just a few steps of code to get it to work. It is even easier in the newer releases where the order of how to process form data has been solved.

The first thing to to in order to have the upload display as a browse button is to extend the form with an input field for a file upload. This can be done by creating a new form element.

$uploadFile = new Zend_Form_Element_File('uploadFile');
$uploadFile->setLabel('Attach file')
           ->setDestination(APPLICATION_PATH.'/../data/original');

This will create a form tag in HTML as:

<form id="uploadImageForm" enctype="multipart/form-data" method="post" class="form-horizontal" 
 action="/productmanager/product/uploadImage/id/15978">

The upload input object generated is.

<input type="hidden" name="MAX_FILE_SIZE" value="2097152" id="MAX_FILE_SIZE">
<input type="file" name="uploadFile" id="uploadFile">

There are additional settings that can be specified on the upload form to limit size of file, mime type or file extension accepted. See more details about that in the Zend Framework online reference.

In the Controller, you just need to process the form as usual by getting the values and then receiving of the new file will be to the target directory specified in the setDestination() method of the form element. If you don't want to decide directory in the form class, it can be set after creating the form in the controller too.

Setting the destination in the controller

$form = new Application_Form_UploadImageForm();
$form->uploadFile->setDestination(APPLICATION_PATH.'/../data/original');

Receiving the file

if ($testForm->isValid($this->_request->getPost())) {
  // Receive values
  $values = $form->getValues();
    			
  try {
    $form->uploadFile->receive();
    Zend_Debug::dump($form->uploadFile->getFileName());
  } catch (Zend_File_Transfer_Exception $e) {
    echo $e->message();
  }
}

When the form is processed, the file is uploaded using it's original name in the folder specified as Destination.

Changing the password in Windows 2008 using RDP

Using Ctrl-Alt-delete in Remote Desktop is not possible

I have often stumbled ona problem when using remote desktop, that is is diffecult to figure out where to change the password. Since there are probably several others with the same problem, I am writing a short note on this to be able to help others.

When you want to change password using Remote Desktop and Windows 2008 Server, use the key sequence Ctrl-Alt-End to get to Windows Security. Then there is the option to change password.

This Ctrl-Alt-End is there as an alternative since you can not use Ctrl-Alt-Delete to enter windows security in a remote desktop session.

I do hope this is useful information for you too!

Spring Framework 3 and property values from already defined beans

An issue when working with configurations in XML-files and property files is how to avoid duplication of configuration data. Spring Framework has given us several ways to do it and two of my favourites are:

  • Importing a property file using and using properties from that file
  • Using an already defined beans properties in other beans

Since Spring Framework 3.0 it is possible to refer to existing beans and its properties using the #{bean.property} syntax. This may be helpful to not repeat information in a XML file. To illustrate what I mean, I have created a project named projectX with a Configuration class that will hold parts of the configuration used in several parts of the project.

In the example, I have the configuration bean named projectConfiguration where I am creating a dataSource bean with properties from the database in the Configuration class.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
    <!-- Project X Configuration bean -->
    <bean id="projectConfig" class="se.fgsoft.projectX.config.Configuration">
        <property name="dbDriver" value="com.ibm.db2.jcc.DB2Driver" />
        <property name="dbUrl" value="jdbc:db2://amanda.local:50000/icmnlsdb" />
        <property name="dbUser" value="icmadmin" />
        <property name="dbPassword" value="xxxxxx" />
    </bean>

    <!-- Data Source using settings from Project X Configuration bean -->
    <bean id="dataSource"
        class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="#{projectConfig.dbDriver}"/>
        <property name="url" value="#{projectConfig.dbUrl}"/>
        <property name="username" value="#{projectConfig.dbUser}"/>
        <property name="password" value="#{projectConfig.dbPassword}"/>
    </bean>

</beans>

This syntax is not limited to bean properties set within the configuration file, it may use any get-method of a bean already initialized, which makes it possible to use a calculated value as a property for another bean.

Extract extension and name from a Filename in Java

Files and file names are often identified by their extension. There are several ways of doing this and by searching the net for solutions, many of them are missing the fact that there may be files without extension that would cause out-of-range exceptions to occur.

This is a piece of Java-code to extract the two parts of a file name as:

  • name.extension
  • Name being the first part of the file name until the last dot
  • Extension being the last part of the filename after the last dot

The name is allowed to contain one or more dots. If a dot exits, it will be used as the separator, which means that the logic would work like this:

  • document1.doc gives name=document1 and extension=doc
  • 1.document.doc gives name=1.document and extension=doc
  • 1.document gives name=1 and extension=document which may be the case for a file created in Mac
  • document gives name=document and extension=NULL
  • .document gives name=empty string and extension=document

Below is sample Java code to extract name and extension from a filename as string.

    /**
     * Return the name part of a file of format name.ext using the filename
     * as a string. If you have a File object, just pass the file.getName() to
     * this function.
     *
     * @param filename The filename as string
     * @return The name, will return null if file does not contain a dot
     */
    public static String getNameFromFilename(String filename) {
        int lastDot = filename.lastIndexOf(".");
        if( lastDot >= 0  ) {
            return filename.substring(0, lastDot);
        }

        return null;
    }

    /**
     * Get the file extension from a filename of format name.ext using the
     * filename as string.
     *
     * @param filename The filename as string
     * @return The extension, will return null if filename does not contain a dot
     */
    public static String getExtensionFromFilename(String filename) {
        int lastDot = filename.lastIndexOf(".");
        if( lastDot >= 0 && lastDot < filename.length()  ) {
            return filename.substring(lastDot+1, filename.length());
        }

        return null;
    }

Unit tests just to give an example for how to use it in context.

    public void testGetNameFromFilename() throws Exception {
        assertEquals("document1", FilenameUtil.getNameFromFilename("document1.doc"));
        assertEquals("document.1", FilenameUtil.getNameFromFilename("document.1.doc"));
        assertEquals("",FilenameUtil.getNameFromFilename(".doc"));
        assertEquals(null, FilenameUtil.getNameFromFilename(""));
    }

    public void testGetExtensionFromFilename() throws Exception {
        assertEquals("doc", FilenameUtil.getExtensionFromFilename("document1.doc"));
        assertEquals("doc", FilenameUtil.getExtensionFromFilename("document.1.doc"));
        assertNull(FilenameUtil.getExtensionFromFilename("document1"));
        assertEquals("",FilenameUtil.getExtensionFromFilename("document1."));
    }

Using a database logger with ZendFramework

Logging in an application is important for many reasons. Often, there are problems to reach an updating file on a server, so other options for logging may be relevant such as using a database table to store log-data

In ZendFramework, there are several loggers to choose between, such as logging to file or using headers to Firebug, but in this example, I have selected to focus on the Zend_Log_Writer_Db.

The database logger will write to a database table that you created and will use a column mapping to select which columns that will be used for storing the log data. This includes the columns:

  • priority
  • message
  • timestamp
  • priorityName

Since you may need to use the logger in the application, it is a good idea to create a method in the Bootstrap.php file to initialize the logger and store it in the registry for easy retrieval in the application.

This example uses the default database defined in the application.ini with my settings as:

resources.db.adapter = "PDO_MYSQL"
resources.db.params.host = "127.0.0.1"
resources.db.params.port = "3306"
resources.db.params.username = "xxxxxxx"
resources.db.params.password = "xxxxxxx"
resources.db.params.dbname = "jusote"

The database table is created as:

CREATE TABLE logger (
  timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  priority` varchar(30) ,
  priorityName` varchar(40) ,
  message text 
) 

My method in Bootstap.php

protected function _initLogger() 
{
	$columnMapping = array('priority' => 'priority', 'message' => 'message',
			'timestamp' => 'timestamp', 'priorityName' => 'priorityName');
		
		
	$resource = $this->getPluginResource('db');
	$db = $resource->getDbAdapter();
		
	$writer = new Zend_Log_Writer_Db($db, 'logger', $columnMapping);
	$logger = new Zend_Log($writer);
 
	Zend_Registry::set('logger', $logger);
}

The log can then later be retrieved and used as

$logger = Zend_Registry::get('logger');	
$logger->log('RunTestsession.run() Starting for session id=' . $testsessionId , Zend_Log::INFO);

About the Author

This blog is written by Fredrik Gustavsson, Boden, Sweden. I have been into professional software development since 1989 and have seen what has happened over the years.

With this blog, I will share my experiences when developing for the "Cloud" comparing the Google and Microsoft solutions

RSS