Created
August 21, 2013 07:25
-
-
Save robksawyer/6291290 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
App::uses('AppModel', 'Model'); | |
App::uses('AttachmentBehavior', 'Uploader.Model/Behavior'); | |
App::uses('FileValidationBehavior', 'Uploader.Model/Behavior'); | |
/** | |
* Attachment Model | |
* | |
* @property User $User | |
* @property CheeseProducer $CheeseProducer | |
* @property Cheese $Cheese | |
* @property User $User | |
*/ | |
use Aws\Common\Enum\Region; | |
class Attachment extends AppModel { | |
/** | |
* Display field | |
* | |
* @var string | |
*/ | |
public $displayField = 'name'; | |
//Resize properties | |
public $imageSmallWidth = '75'; | |
public $imageSmallAppend = '_small'; | |
public $imageSmallDBCol = 'path_small'; | |
// | |
public $imageMedWidth = '320'; | |
public $imageMedAppend = '_med'; | |
public $imageMedDBCol = 'path_med'; | |
public $currentModelID = null; | |
public $currentModel = null; | |
public $uploadDir = null; //The main path to upload the attachment to | |
public $finalPath = null; //The path that is appended to records in the database | |
public $modelClass = null; //The model to save in the database as a reference | |
public $modelId = null; //The model id to save in the database as a reference | |
public $bucket = null; //The S3 Bucket that the attachment lives in | |
//The Associations below have been created with all possible keys, those that are not needed can be removed | |
public $actsAs = array( | |
'Containable', | |
'Uploader.FileValidation' => array( | |
'fileName' => array( | |
'type' => array('image'), //The type value can be anything before the / in the mime type declarations. | |
'required' => false, | |
'minWidth' => 150, | |
'minHeight' => 150, | |
'filesize' => 10485760 //10 MB | |
) | |
), | |
'Uploader.Attachment' => array( | |
'fileName' => array( | |
'nameCallback' => 'formatFileName', | |
'overwrite' => true, | |
'stopSave' => false, | |
'required' => false, | |
'dbColumn' => 'path', | |
'uploadDir' => '/tmp', | |
'finalPath' => '/', | |
'metaColumns' => array( | |
'name' => 'name', | |
'ext' => 'extension', | |
'type' => 'mimeType', | |
'size' => 'fileSize', | |
'width' => 'width', | |
'height' => 'height' | |
), | |
'transforms' => array( | |
'path_small' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'resize', | |
'overwrite' => true, | |
'width' => 75 | |
), | |
'path_small_crop' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'crop', | |
'append' => '_crop', | |
'overwrite' => true, | |
'width' => 75, | |
'height' => 75 | |
), | |
'path_med' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'resize', | |
'overwrite' => true, | |
'width' => 250 | |
), | |
'path_med_crop' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'crop', | |
'append' => '_crop', | |
'overwrite' => true, | |
'height' => 250, | |
'width' => 250 | |
), | |
'path_large' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'resize', | |
'expand' => true, | |
'overwrite' => true, | |
'width' => 640 | |
), | |
'path_large_crop' => array( | |
'nameCallback' => 'transformName', | |
'method' => 'crop', | |
'append' => '_crop', | |
'expand' => true, | |
'overwrite' => true, | |
'height' => 640, | |
'width' => 640 | |
) | |
), | |
'transport' => array( | |
'class' => AttachmentBehavior::S3, | |
'accessKey' => CC_S3_ACCESS_KEY, | |
'secretKey' => CC_S3_SECRET_KEY, | |
'bucket' => '', | |
'region' => Aws\Common\Enum\Region::US_WEST_2, | |
'folder' => '', | |
'meta' => array( | |
'ext' => 'extension', | |
'type' => 'mimeType', | |
'size' => 'fileSize', | |
'width' => 'width', | |
'height' => 'height' | |
) | |
) | |
) | |
) | |
); | |
/** | |
* belongsTo associations | |
* | |
* @var array | |
*/ | |
public $belongsTo = array( | |
'User' => array( | |
'className' => 'User', | |
'foreignKey' => 'user_id', | |
'conditions' => '', | |
'fields' => '', | |
'order' => '' | |
) | |
); | |
/** | |
* hasMany associations | |
* | |
* @var array | |
*/ | |
public $hasMany = array( | |
'Badge' => array( | |
'className' => 'Badge', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'CheeseProducer' => array( | |
'className' => 'CheeseProducer', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'CheeseProducerLocation' => array( | |
'className' => 'CheeseProducerLocation', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'CheeseLocation' => array( | |
'className' => 'CheeseLocation', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'CheeseRegion' => array( | |
'className' => 'CheeseRegion', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'Cheese' => array( | |
'className' => 'Cheese', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'CheeseType' => array( | |
'className' => 'CheeseType', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'User' => array( | |
'className' => 'User', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'AnimalBreed' => array( | |
'className' => 'AnimalBreed', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'Affineur' => array( | |
'className' => 'Affineur', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'Cheesemaker' => array( | |
'className' => 'Cheesemaker', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'Place' => array( | |
'className' => 'Place', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
), | |
'MilkSource' => array( | |
'className' => 'MilkSource', | |
'foreignKey' => 'attachment_id', | |
'dependent' => false, | |
'conditions' => '', | |
'fields' => '', | |
'order' => '', | |
'limit' => '', | |
'offset' => '', | |
'exclusive' => '', | |
'finderQuery' => '', | |
'counterQuery' => '' | |
) | |
); | |
/** | |
* beforeSave Callback | |
* @link http://book.cakephp.org/2.0/en/models/callback-methods.html | |
* @param array $options | |
*/ | |
public function beforeSave($options = array()){ | |
if(isset($this->data[$this->alias]['fileName']) && $this->data[$this->alias]['fileName']['size'] > 0){ | |
if(empty($this->modelClass)){ | |
throw new InvalidArgumentException('You did not provide a model name.'); | |
} | |
/*if(empty($this->modelId)){ | |
throw new InvalidArgumentException('You did not provide a model id.'); | |
}*/ | |
//If a new attachment exists, delete the old one. | |
if(!empty($this->data[$this->modelClass]['attachment_id'])){ | |
$success = $this->removeAttachment($this->data[$this->modelClass]['attachment_id']); | |
$this->data[$this->modelClass]['attachment_id'] = null; | |
} | |
$this->data[$this->alias] = $this->processAttachment(); | |
}else{ | |
unset($this->data[$this->alias]['fileName']); //Unset data to prevent a new record from being created. | |
} | |
debug($this->data); | |
return true; | |
} | |
/** | |
* beforeValidate Callback | |
* Handles finding out whether or not the user added an image via a URL | |
* @param array $options | |
*/ | |
public function beforeValidate($options = array()){ | |
if(!empty($this->data[$this->alias]['fileNameUrl'])){ | |
unset($this->data[$this->alias]['fileName']); | |
$this->data[$this->alias]['fileName'] = $this->data[$this->alias]['fileNameUrl']; | |
unset($this->data[$this->alias]['fileNameUrl']); | |
} | |
return true; | |
} | |
/** | |
* beforeTransform Callback | |
* @param array $options | |
*/ | |
/*public function beforeTransform($options){ | |
if(empty($this->uploadDir)){ | |
throw new InvalidArgumentException('You did not provide an upload directory.'); | |
} | |
if(empty($this->finalPath)){ | |
$this->finalPath = preg_replace('/'.IMAGES. 'uploads\//','',$this->uploadDir); | |
} | |
$options['uploadDir'] = $this->uploadDir; | |
$options['finalPath'] = $this->finalPath; | |
return $options; | |
}*/ | |
/** | |
* beforeTransport Callback | |
* @param array $options | |
*/ | |
public function beforeTransport($options){ | |
if(empty($this->bucket)){ | |
throw new InvalidArgumentException('You did not provide an Amazon S3 bucket.'); | |
} | |
$options['bucket'] = $this->bucket; | |
return $options; | |
} | |
/** | |
* Format the filename a specific way before uploading and attaching. | |
* | |
* @access public | |
* @param string $name - The current filename without extension | |
* @param string $field - The form field name | |
* @param array $file - The $_FILES data | |
* @return string | |
*/ | |
public function formatFileName($name, $file) { | |
//$name = $this->sanitize_file_name($name); | |
if(!empty($this->modelId)){ | |
$name = $this->modelClass . "_" . $this->modelId; | |
}else{ | |
$date = new DateTime(); //Create a Date | |
$stamp = $date->format('m_d_Y_H-i-s'); | |
$name = $this->alias . "_" . $stamp; | |
} | |
//$this->data[$this->alias]['name'] = $name; | |
return $name; | |
} | |
/** | |
* transformName Callback | |
* @param $name | |
* @param $file | |
* @link http://milesj.me/code/cakephp/uploader | |
*/ | |
public function transformName($name, $file) { | |
$fWidth = $file->width(); | |
$fHeight = $file->height(); | |
if(!empty($fWidth) && !empty($fHeight)){ | |
$name = preg_replace('/-resize/', '', $this->getUploadedFile()->name()); | |
$name = $name . '-' . $file->width(); | |
}else{ | |
$name = preg_replace('/-resize/', '', $name); | |
} | |
return $name; | |
} | |
/** | |
* processAttachment method | |
* This method simply handles processing the image data and building an array of useful data to be saved. | |
* @param void | |
* @return array Attachment data formatted | |
*/ | |
public function processAttachment(){ | |
$timestamp = date("Y-m-d H:m:s", time()); //Create a timestamp | |
if(empty($model->data[$this->alias]['edit_user_id'])){ | |
$this->data[$this->alias]['edit_user_id'] = ''; | |
} | |
if(empty($this->data[$this->alias]['active'])) $this->data[$this->alias]['active'] = 1; //Default to active | |
if(!isset($this->data[$this->alias]['name']) || empty($this->data[$this->alias]['name'])){ | |
$this->data[$this->alias]['name'] = uniqid(); | |
} | |
$formattedData = array( | |
'name' => $this->data[$this->alias]['name'], | |
'bucket' => $this->bucket, | |
'group' => 'image', | |
'model' => $this->modelClass, | |
//'model_id' => $this->modelId, //Only exists on the edit form | |
'active' => $this->data[$this->alias]['active'], | |
'uploaded' => $timestamp | |
); | |
if(!isset($this->data[$this->alias]['width']) || !isset($this->data[$this->alias]['height'])){ | |
CakeLog::error('A width or height was not found. This image will not render properly.'); | |
}else{ | |
$formattedData['width'] = $this->data[$this->alias]['width']; | |
$formattedData['height'] = $this->data[$this->alias]['height']; | |
} | |
if(isset($this->data[$this->alias]['user_id'])) $formattedData['user_id'] = $this->data[$this->alias]['user_id']; | |
if(isset($this->data[$this->alias]['edit_user_id'])) $formattedData['edit_user_id'] = $this->data[$this->alias]['edit_user_id']; | |
if(isset($this->data[$this->alias]['path'])) $formattedData['path'] = $this->data[$this->alias]['path']; | |
if(isset($this->data[$this->alias]['path_small'])) $formattedData['path_small'] = $this->data[$this->alias]['path_small']; | |
if(isset($this->data[$this->alias]['path_small_crop'])) $formattedData['path_small_crop'] = $this->data[$this->alias]['path_small_crop']; | |
if(isset($this->data[$this->alias]['path_med'])) $formattedData['path_med'] = $this->data[$this->alias]['path_med']; | |
if(isset($this->data[$this->alias]['path_med_crop'])) $formattedData['path_med_crop'] = $this->data[$this->alias]['path_med_crop']; | |
if(isset($this->data[$this->alias]['path_large'])) $formattedData['path_large'] = $this->data[$this->alias]['path_large']; | |
if(isset($this->data[$this->alias]['path_large_crop'])) $formattedData['path_large_crop'] = $this->data[$this->alias]['path_large_crop']; | |
if(isset($this->data[$this->alias]['source_url'])) $formattedData['source_url'] = $this->data[$this->alias]['source_url']; | |
if(isset($this->data[$this->alias]['mimeType'])) $formattedData['type'] = $this->data[$this->alias]['mimeType']; | |
if(isset($this->data[$this->alias]['extension'])) $formattedData['ext'] = $this->data[$this->alias]['extension']; | |
if(isset($this->data[$this->alias]['fileSize'])){ | |
$formattedData['size'] = $this->data[$this->alias]['fileSize']; | |
$formattedData['filesize'] = $this->filesize_format($this->data[$this->alias]['fileSize']); | |
} | |
CakeLog::info(json_encode($formattedData)); | |
return $formattedData; | |
} | |
/** | |
* Removes the attachment from the file system and deletes the record from the db | |
* Note: The method also makes sure that the attachment is not being used by any other record first though. | |
* @param string id The attachment id | |
* @return bool Whether or not the deletion was a success or not | |
*/ | |
public function removeAttachment($id = null){ | |
$attachment = $this->find('first',array( | |
'conditions' => array('Attachment.id' => $id), | |
'fields' => array('id'), | |
'recursive' => -1 | |
)); | |
if(!empty($attachment['Attachment']['id'])){ | |
//Delete the record | |
if($this->deleteFiles($attachment['Attachment']['id'],array('path_small','path_small_crop','path_med','path_med_crop','path_large','path_large_crop'))){ | |
//$deleteSuccess = $this->deleteFiles($attachment['Attachment']['id']); | |
//Delete success | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Function: sanitize | |
* Returns a sanitized string, typically for URLs. | |
* | |
* Parameters: | |
* $string - The string to sanitize. | |
* $force_lowercase - Force the string to lowercase? | |
* $anal - If set to *true*, will remove all non-alphanumeric characters. | |
*/ | |
public function sanitize_file_name($string, $force_lowercase = true, $anal = false) { | |
$strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]", | |
"}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—", | |
"—", "–", ",", "<", ".", ">", "/", "?"); | |
$clean = trim(str_replace($strip, "", strip_tags($string))); | |
$clean = preg_replace('/\s+/', "-", $clean); | |
$clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean ; | |
return ($force_lowercase) ? | |
(function_exists('mb_strtolower')) ? | |
mb_strtolower($clean, 'UTF-8') : | |
strtolower($clean) : | |
$clean; | |
} | |
/** | |
* filesize_format method | |
* Formats the filesize | |
* @link http://codebyte.dev7studios.com/post/1590919646/php-format-filesize | |
*/ | |
public function filesize_format($size, $sizes = array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')) { | |
if ($size == 0) return('n/a'); | |
return (round($size/pow(1024, ($i = floor(log($size, 1024)))), 2) . ' ' . $sizes[$i]); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment