Skip to content

Instantly share code, notes, and snippets.

@johnkary
Created October 25, 2011 15:43
Show Gist options
  • Save johnkary/1313191 to your computer and use it in GitHub Desktop.
Save johnkary/1313191 to your computer and use it in GitHub Desktop.
Symfony 1 validator for Microsoft Office 2007 docs
<?php
/**
* Adds MIME-type guessers for Office 2007 documents
*
* @author John Kary <johnkary@ku.edu>
*/
class sfValidatorOffice2007File extends sfValidatorFile
{
/**
* Office 2007 MIME-types by file extension
*
* @var array
*/
protected $office2007MimeTypes = array(
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
);
protected function configure($options = array(), $messages = array())
{
parent::configure($options, $messages);
$this->setOption('mime_type_guessers', array(array($this, 'guessOffice2007WordDoc')) + $this->getOption('mime_type_guessers'));
}
/**
* Guesses Office 2007 MIME-type of file, if applicable
*
* @param string $file Absolute path to the file
* @return string The mime type of the file (null if not guessable)
*/
protected function guessOffice2007WordDoc($file)
{
if (!$this->isZipMimeType($file)) {
return null;
}
if (!class_exists('ZipArchive')) {
//PHP not compiled with zip extension
return null;
}
$zip = new \ZipArchive();
if (!$zip->open($file)) {
//Unable to open zip file
return null;
}
if (!$zip->getFromName('[Content_Types].xml')) {
//Not a valid Office 2007+ document
return null;
}
//@todo - More stringent validation of files in archive
// - Unzip contents to dir
// - Get list of all files in zip archive dir
// - Invalid if directory levels greater than 10
// - Validate all MIME-types of files against whitelist
// - Must be: XML or image files validated by getimagesize($file)
//Assuming it's a DOCX for now
return $this->office2007MimeTypes['docx'];
}
/**
* Checks if a file is a valid ZIP file based on returned MIME-type
*
* @param string $file Absolute path to file
* @return boolean
*/
protected function isZipMimeType($file)
{
return ('application/zip' == $this->guessFromFileinfo($file));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment