Category: "Web Applications"

Open Source Software and House Paint

If you think about it, free or inexpensive open source software is like house paint. The product is readily available and doesn't cost a lot, but can be very valuable. A good open source software system such as a content management system, ecommerce system, forum or blog can transition a simple site into one that offers site visitors services and may provide important revenue for a company. A can of paint can transform a worn exterior or tired interior into fresh welcoming walls, making a home more attractive and valuable.

In both cases the most important element is the skill used to apply the product.

Software must be visually appealing, easy to use, and it must work. A designer or user interface person can layout the page, a developer must code the HTML and it must then be integrated into the system. Installation, configuration and customization are required to bring the application to life. Simply put, most powerful open source software requires a significant amount of skill and experience across the full spectrum of web development.

The same is true of paint and parallels the skills required for software. From a design perspective, the color and finish must be chosen carefully to match where the paint will be used. The walls must be prepared, including thorough removal of any wallpaper, patching any holes or dents, the floor must be covered, and areas that require masking tape have to be readied. Choosing the right tools is important, from ladders to paint brushes.

What's the point of this post?

That the expense of the paint or software doesn't reflect the cost to benefit from it.

Many people assume that because the software is free it shouldn't cost anything if they want to use it on their site. If there is a web company that is using that product, there is usually a significant skill investment required. Those skills are the difference between a secure, polished, functional, reliable and stable site and an awkward site that is far less credible.

Yesterday I bought a gallon of light blue paint for about $25. The walls had been prepared a few weeks ago, there was probably 10 hours of work stripping off the old wallpaper, soaking off the paper backing, and removing the wallpaper paste. A small can of spackle filled in the minor imperfections. The first coat of paint took three hours to apply and it came out nicely. It is mostly evenly distributed, there is very little paint where it shouldn't be, and the finish is fairly uniform. One more coat will complete the project. The true cost of the project is the labor to put the paint on the wall nicely, not the can of paint itself. Just like open source software.

Cleaning up files created by the web server

Many times when you are working with a web application on shared hosting, the server will create files. Depending on the server configuration, it is possible those files will be created by a user other than the account holder. If you are using shared hosting, and the server is running as 'nobody', 'apache' or 'www-root' you may not be able to delete the files.

This script determines the web server user with the whoami command, then finds and deletes any files it owns. Bear in mind it will delete them from the current directory down, so files higher up in the directory tree will not be removed.

<?php
$whoami = `whoami`;
echo $whoami;
$find = 'find -delete -user '.$whoami;
`$find`;

Be careful with this script, it may delete files you wanted to keep.

A good practice is to use the whoami display to see which user the server is running as, then use find -user server to find the files that were created. Once you've checked it, you can allow the script to run. Remember to run the script through the browser or using wget.

Zend Framework - No translation for the language 'en_US' available.

Notice: No translation for the language ‘en_US’ available. in /var/www/html/ZendFramework-1.10.8-minimal/library/Zend/Translate/Adapter.php on line 441

I’ve been working on an application using Zend Framework as the foundation. One of the key elements is ensuring internationalization/i18n support, and the error above was being displayed.

In addition to translating page text, I wanted to add htmlentities
conversion, without calling it explicitly.

I created an adapter which extends the Gettext adapter.


<?php

Class CLOUD_Translate_Adapter_Gettext Extends Zend_Translate_Adapter_Gettext
{
    public function translate($messageId, $locale = null)
    {
		return htmlentities(parent::translate($messageId,$locale),ENT_QUOTES,'UTF-8');
	}
}

To prevent the error from being displayed, I changed:

        
$translate = new Zend_Translate(array('adapter'=>'CLOUD_Translate_Adapter_Gettext',
                'content'=>$language_path,
                'scan' => Zend_Translate::LOCALE_DIRECTORY,
                'locale'=>$locale->toString()));
$translate->setOptions(array('disableNotices'=>true));

to:


$translate = new Zend_Translate(array('adapter'=>'CLOUD_Translate_Adapter_Gettext',
                'content'=>$language_path,
                'scan' => Zend_Translate::LOCALE_DIRECTORY,
                'locale'=>$locale->toString(),
                'disableNotices'=>true));

The difference is that disableNotices is included in the instantiation, so that as it initializes the translation object, detected errors are not reported.

Since the default language for the page is en-US, there is no need for translation.

Key Cloud Service Architecture Considerations

Converting an existing product or service for use in the cloud should begin with a consideration of several key requirements. Simply extending a system to support more clients may result in serious security, performance, and scalability issues.

These core requirements should be addressed prior to the application specific features, they represent the foundation for the system. These common elements apply for virtually any cloud based service.

  • Secure - The system must be designed and developed with best practices for security.
  • Scalable - The system must be scalable, to allow additional organizations to join without impacting others. The system capacity must be able to grow as necessary.
  • Manageable - It must be possible to adjust the resource allocation in response to changing consumption. If one server is too busy, clients should be able to be moved to a different server, with minimal service impact.
  • Fault Tolerant - System outages should be minimized and a disaster recovery plan must be in place. This includes backup and restore procedures, whether the failure or problem is due to a hardware, software, administrator, or user issue.
  • Segmented - Each client or organization must have a separate file system area, or account, and database, and access to these resources should limited as necessary for the use of the data. Failure to organize and protect the data can make it difficult or impossible to secure, scale and manage. Although some service elements may be system or server based, they must be provisioned or partitioned for use in such a way that the data is segmented.
  • Access Paths - Cloud services should allow subscribers to white label, so they can offer the services as if they are their own. Access URLs should be defined by the subscribers, probably as subdomains or derivative domains from their existing architecture.
  • Brandable - It is important that the services be brandable, so clients can identify the system as theirs. The extent of branding can vary, but at a minimum, a corporate logo should be displayed, and some connections or links to the corporate site and support resources should be provided. A neutral color scheme, such as grayscale can make it easier to ensure a nice presentation regardless of the logo.
  • Incremental - A tiered service offering should be established to allow free trials, as well as service levels so clients can purchase only the services they need.
  • Extensible - Cloud offerings should include the ability to extend and integrate with other systems, and those extensions should be managed at the client level. Thus, if one subscriber needs custom code, the code can be added without affecting other clients.
  • Integration - As with extensions, custom integration should be enabled to allow access into client infrastructures without affecting other clients.
  • Turnkey - The base system should be available very quickly, set up time should be minimal.
  • Easy to Use - Examine any existing systems and consider support requests to identify areas that have been difficult for clients to work with. Be sure to consider ways to improve these issues before proceeding.
  • Web Service or API Access - Subscribers should be able to interact with the system through automated processes with standards based interfaces such as SOAP and REST. These interfaces must be well-defined and documented. Test code and interfaces should be provided to ease development.
  • Well Supported - An extension of easy to use, support refers to ensuring users can use the system to do what needs to be done in a timely manner. The application needs to be organized carefully, supported with validation and help on the client (browser) side, adequate documentation, meaning a full manual in PDF, HTML or .zipped, a ticket system and possible a live chat interface.
  • Cost Effective - The cost of the system must be competitive.
  • Service Level Agreement - A service level agreement must be provided. This ensures both the provider and client understand exactly what is being offered.
  • Localization (l10n)
  • Internationalization (i18n)

XML Fed Form Interface

This is a demonstration of how you can use XML to feed PHP to generate a form. It is helpful when a flexible form interface is needed. This example includes the name of the field, the length, a regex validation string, default value, label for the input, whether it is required or not, and error text. It could be extended have multilingual validation and error text.

<?xml version="1.0" encoding="utf-8" ?>
<interface>
        <name>Works</name>
        <fields>
                <field>
                        <name>URL</name>
                        <length>255</length>
                        <validation>[\w\.\-]{2,255}</validation>
                        <default>domain.com</default>
                        <label>URL</label>
                        <value>url.com</value>
                        <required>true</required>
                        <errortext>Letters, numbers, periods and dashes only</errortext>
                </field>
                <field>
                        <name>id</name>
                        <length>11</length>
                        <validation>[\d]{1,11}</validation>
                        <default>1</default>
                        <label>Id</label>
                        <required>true</required>
                        <errortext>Ids must be all digits</errortext>
                </field>
        </fields>
</interface>

This is the PHP that reads the XML. It uses SimpleXML, which is really nice.

<?php echo '<?xml version="1.0" encoding="utf-8" ?>' ?>
<?php
$xml=file_get_contents('bw.xml');
$xmldata = new SimpleXMLElement($xml);
$bValid=true;
/* Validate the submitted data */
if (isset($_POST['submit']))
{
        $bValid=true;
        foreach ($xmldata->fields->field as $f)
                if (isset($_POST["{$f->name}"]))
                {
                        $f->value=$_POST["{$f->name}"];
                        if (!preg_match('/^'.$f->validation.'$/',$_POST["{$f->name}"]))
                        {
                                $f->invalid=(bool)true;
                                $bValid=false;
                        }
                }
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en-US" xml:lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XML Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
label
{
font-weight:bolder;
}
input,label
{
display:block;
}
.invalid
{
color:#f00;
}
</style>
</head>
<body>
<h1>XML Form Sourcing Demo</h1>
<hr />
<h2>Generated Inputs</h2>
<!-- 
Generates the form from the XML data.  Note the use of the invalid flag for highlighting, and the display of
errortext if appropriate.
-->  
<form action="#" method="post">
<?php foreach ($xmldata->fields->field as $f) : ?>
<label <?php if (isset($f->invalid)) echo 'class="invalid"' ?> for="<?php echo $f->name?>"><?php echo (($f->required==
'true')?'*':'').$f->label ?>
<?php if (isset($f->invalid)) echo ' '.$f->errortext; ?>
<input name="<?php echo $f->name ?>" id="<?php echo $f->name ?>"
        maxlength="<?php echo $f->length ?>"
        value="<?php echo (isset($f->value)?$f->value:$f->default) ?>" />
</label>
<?php endforeach ?>
<br />
<input name="submit" type="submit" />
</form>
<h2>Raw XML Data</h2>
<!-- Display the raw XML data, for debugging/development -->
<blockquote><?php echo nl2br(htmlentities(file_get_contents('bw.xml'))) ?></blockquote>
<h2>Parsed XML</h2>
<!-- Display how SimpleXML parsed the XML, again for debugging/development -->
<?php
echo '<pre>';
var_dump($xmldata);
echo '</pre>';
?>
<h2>Updated XML (if valid)</h2>
<!-- Show how the XML was updated, if it was valid -->
<?php
if ($bValid)
        echo '<pre>'.nl2br(htmlentities($xmldata->asXML())).'</pre>';
?>
</body>
</html>

This is well-suited for applications which must use connection data into a variety of external interfaces. In this case, the data can be presented, entered, validated, and stored, then used later by a different process.