Rapid RIA Development

Each step ends with place in version control, submit for review, evaluate review responses and apply them as appropriate..

  1. Define the page architecture, common page elements first. These must be stable before beginning.
  2. Build page level XHTML/CSS for all pages, target browser FireFox, with only enough back end code to deliver the pages. Use static server-side content to populate dynamic controls/queries for illustration. Create data in the database to support it. Validate the XHTML/CSS as well as possible (some libraries have proprietary attributes).
  3. If common components are identified in the previous step, they should be constructed reusable/shared components. For example, a file upload or search results dialog box will probably be used in more than one place. Both client and server-side code should address this to avoid duplicate code.
  4. Tune colors.
  5. Define and implement client-side functionality, allowing content to be delivered through AJAX, navigation, any dynamic operations.
  6. Implement client-side validation.
  7. Extend pages to run under any other browsers you will be supporting. Clearly indicate limitations, such as will function but may not display well. Provide notification for users of unsupported browsers.
  8. Integrate and implement server-side validation. It should be identical to client-side validation, with addition considerations for security.
  9. Implement page level functionality.
  10. Test, test, test.

http://know-waste.com has moved to http://web-notes.wirehopper.com

The registration for the domain name know-waste.com expired, the credit card number had changed, and the most cost-effective solution is to run this blog as a subdomain.

Web Development - Horizontal and Vertical Markets

Horizontal

http://en.wikipedia.org/wiki/Horizontal_market

  • Web sites
  • Intranets
  • ecommerce
  • Live support
  • Social networking / web 2.0
  • Blogs
  • Flash
  • RSS / aggregation
  • SEO
  • Internet Marketing

Vertical

http://en.wikipedia.org/wiki/Vertical_market

  • Application development, including RIAs
  • email management
  • Server management
  • Licensing
  • Toolkit / Framework development
  • Technical support
  • Product support
  • Open source customization
  • Content Delivery Networks

Quick Scan of /etc/httpd/logs/access_log to Identify Visitors

If you don’t have web stats running on your server, but you’d like to see who is visiting the pages, the following lines can be used.


cut -f1 -d' ' /etc/httpd/logs/access_log* | sort | uniq 

host IPADDR

The first line extracts the requesting IP addresses, sorts them, and then removes any duplicates. The second can be used to get the hostname for the IP address, if it is available.

PHP File Upload Example

This example shows the HTML and PHP to upload a file.

Browsers handle the MAX_FILE_SIZE input and accept attribute differently. Some will filter the files offered through the dialog box to only list those identified by the accept attribute. Some will allow you to select a file that is too large, and submit it to the server, without any content. In this case, the tmp_name is empty, error is 2, and size is 0.

In all cases you must validate the file on the server side.

HTML to upload a file:


<?php define('FILE_UPLOAD_MAX',min(str_replace('M','000000',ini_get('upload_max_filesize')),str_replace('M','000000',ini_get('post_max_size'))));
 ?>
<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>upload demo</title>
		<link href="upload.css" rel="stylesheet">
	</head>
	<body>
		<h1>upload demo</h1>
		<form method="post" enctype="multipart/form-data" action="upload-file.php">
			<input type="hidden" name="MAX_FILE_SIZE" value="<?= FILE_UPLOAD_MAX ?> " >
			<div class="block">
				<label for="file">File</label>
				<input type="file" name="file" id="file" value="" accept="image/*">
			</div>
			<button type="submit">Go</button>
		</form>
	</body>
</html>

PHP to accept it:


<?php
header('Content-Type: text/plain');
define('MAX_FILE_SIZE',min(
        str_replace('M','000000',ini_get('upload_max_filesize')),
        str_replace('M','000000',ini_get('post_max_size'))));

function is_accepted($sAccept,$sFiletype) {
        $aAccept=explode(',',$sAccept);
        return in_array($sFiletype,$aAccept,TRUE);
}

function size_ok($iMaxSize,$iSize) {
        return $iSize <= $iMaxSize;
}

function upload(&$files,$sAccept='*/*',$iMaxSize=MAX_FILE_SIZE) {
        foreach ($_FILES as $k => $v) {
                if ($v['tmp_name']==='') {
                        continue;
                }
                // More robust type checking: https://www.php.net/manual/en/features.file-upload.php#114004
                if (!is_accepted($sAccept,$v['type'])) {
                        throw new Exception($v['type'].' files cannot be sent');
                }
                if (!size_ok($iMaxSize,$v['size'])) {
                        throw new Exception('File cannot be larger than '.$iMaxSize);
                }

               // do antivirus scan here
               $vname = $v['tmp_name'];
               system('clamscan '.escapeshellarg($vname),$result);
               echo $result;
               if ($result !== 0) {
                  die;
              }
              echo 'Scanned okay';
                // Thanks to: https://www.php.net/manual/en/features.file-upload.php#114004
                // strip out anything other than letters, digits, underscores, periods and dashes
                $name = preg_replace('/[^\w.-]/','',$v['name']);
                if ($name === '') {
                        throw new Exception('Invalid filename');
                }
                if (!move_uploaded_file($v['tmp_name'], $name)) {
                        throw new Exception('Upload failed');
                }
                $element = [
                        'filename' => $name,
                        'file' => $v['tmp_name'],
                        'content_type' => $v['type'] ];
                $files[] = $element;
        }
        return true;
}

$uploadFiles = [];
try {
        if (upload($uploadFiles, 'image/png,image/jpg,image/jpeg,image/gif', MAX_FILE_SIZE)) {
                var_dump($uploadFiles);
        } else {
                echo 'Upload failed';
        }
} catch (Exception $e) {
        echo $e->getMessage().PHP_EOL;
        error_log('File upload failed '.$e->getMessage());
}