00001 <?php
00002
00024 class SnapContentMediaImage extends SnapContent {
00025
00026 const TITLE_NAME = "_name";
00027
00028 const TITLE_DESC = "_desc";
00029
00030 const ALT_NAME = "_name";
00031
00032 const ALT_DESC = "_desc";
00033
00034
00042 protected function getSuffix() {
00043 if(!$this->validate())
00044 return false;
00045
00046 return $this->get('format');
00047 }
00048
00049
00057 protected function doDelete() {
00058 if(!$this->validate())
00059 return true;
00060
00061 $original = new SnapExternalFile($this->version, $this->get('original'));
00062 $thumb = new SnapExternalFile($this->version, $this->get('thumb'));
00063 $medium = new SnapExternalFile($this->version, $this->get('medium'));
00064 $display = new SnapExternalFile($this->version, $this->get('display'));
00065
00066 $original->delete();
00067 $thumb->delete();
00068 $medium->delete();
00069 $display->delete();
00070
00071 return true;
00072 }
00073
00074
00082 protected function doCopy() {
00083 $newCM = new SnapContentMediaImage($this->version);
00084
00085 $original = new SnapExternalFile($this->version, $this->get('original'));
00086 $thumb = new SnapExternalFile($this->version, $this->get('thumb'));
00087 $medium = new SnapExternalFile($this->version, $this->get('medium'));
00088 $display = new SnapExternalFile($this->version, $this->get('display'));
00089
00090 $ocopy = $original->copy();
00091 $tcopy = $thumb->copy();
00092 $mcopy = $medium->copy();
00093 $dcopy = $display->copy();
00094
00095 $okay = true;
00096 if(!$ocopy) {
00097 $this->setError('Could not copy original image: <ul><li>' . implode('</li><li>', $original->getError())
00098 . '</li></ul>');
00099 $okay = false;
00100 }
00101 if(!$tcopy) {
00102 $this->setError('Could not copy thumb image: <ul><li>' . implode('</li><li>', $thumb->getError())
00103 . '</li></ul>');
00104 $okay = false;
00105 }
00106 if(!$mcopy) {
00107 $this->setError('Could not copy medium image: <ul><li>' . implode('</li><li>', $medium->getError())
00108 . '</li></ul>');
00109 $okay = false;
00110 }
00111 if(!$dcopy) {
00112 $this->setError('Could not copy display image: <ul><li>' . implode('</li><li>', $display->getError())
00113 . '</li></ul>');
00114 $okay = false;
00115 }
00116 if(!$okay) {
00117 if($ocopy) $ocopy->delete();
00118 if($tcopy) $tcopy->delete();
00119 if($mcopy) $mcopy->delete();
00120 if($dcopy) $dcopy->delete();
00121 return false;
00122 }
00123
00124 $newCM->set('original', $ocopy->getArray());
00125 $newCM->set('thumb', $tcopy->getArray());
00126 $newCM->set('medium', $mcopy->getArray());
00127 $newCM->set('display', $dcopy->getArray());
00128
00129 $newCM->set('original_width', $this->get('original_width'));
00130 $newCM->set('original_height', $this->get('original_height'));
00131 $newCM->set('thumb_width', $this->get('thumb_width'));
00132 $newCM->set('thumb_height', $this->get('thumb_height'));
00133 $newCM->set('medium_width', $this->get('medium_width'));
00134 $newCM->set('medium_height', $this->get('medium_height'));
00135 $newCM->set('display_width', $this->get('display_width'));
00136 $newCM->set('display_height', $this->get('display_height'));
00137 $newCM->set('format', $this->get('format'));
00138
00139 $newCM->set('config', $this->get('config'));
00140
00141 return $newCM;
00142 }
00143
00144
00152 protected function validate() {
00153 $values = $this->getAll();
00154 if(!isset($values['thumb']) || !isset($values['medium'])
00155 || !isset($values['display']) || !isset($values['original'])
00156 || !isset($values['format'])
00157 || !isset($values['thumb_width']) || !isset($values['thumb_height'])
00158 || !isset($values['medium_width']) || !isset($values['medium_height'])
00159 || !isset($values['display_width']) || !isset($values['display_height'])
00160 || !isset($values['original_width']) || !isset($values['original_height']))
00161 return false;
00162 else
00163 return true;
00164 }
00165
00166
00175 protected function doGetHTML($params) {
00176 if(!$this->validate()) {
00177 return false;
00178 }
00179
00180 if(!isset($params['which']))
00181 $params['which'] = 'original';
00182
00183 if(isset($params['class']) && $params['class'] != "")
00184 $class = " class=\"$params[class]\"";
00185 else $class = "";
00186
00187 if(isset($params['id']) && $params['id'] != "")
00188 $id = " id=\"$params[id]\"";
00189 else $id = "";
00190
00191 if(isset($params['ismap']) && $params['ismap'] != "")
00192 $ismap = " ismap=\"$params[ismap]\"";
00193 else $ismap = "";
00194
00195 if(isset($params['usemap']) && $params['usemap'] != "")
00196 $usemap = " usemap=\"$params[usemap]\"";
00197 else $usemap = "";
00198
00199 if(isset($params['alt'])) {
00200 switch($params['alt']) {
00201 case self::ALT_NAME:
00202 $alt = " alt=\"" . str_replace('"', '\\"', $this->version->getResource()->getName()) . "\"";
00203 break;
00204 case self::ALT_DESC:
00205 $alt = " alt=\"" . str_replace('"', '\\"', $this->version->getResource()->getDescription()) . "\"";
00206 break;
00207 default:
00208 $alt = " alt=\"" . str_replace('"', '\\"', $params['alt']) . "\"";
00209 break;
00210 }
00211 }
00212 else $alt = "";
00213
00214 if(isset($params['title'])) {
00215 switch($params['title']) {
00216 case self::TITLE_NAME:
00217 $title = " title=\"" . str_replace('"', '\\"', $this->version->getResource()->getName()) . "\"";
00218 break;
00219 case self::TITLE_DESC:
00220 $title = " title=\"" . str_replace('"', '\\"', $this->version->getResource()->getDescription()) . "\"";
00221 break;
00222 default:
00223 $title = " title=\"" . str_replace('"', '\\"', $params['title']) . "\"";
00224 break;
00225 }
00226 }
00227 else $title = "";
00228
00229 switch($params['which']) {
00230 case 'originalurl':
00231 $tmp = new SnapExternalFile($this->version, $this->get('original'));
00232 return $tmp->getURL();
00233 case 'thumb':
00234 $tmp = new SnapExternalFile($this->version, $this->get('thumb'));
00235 $thumbURL = $tmp->getURL();
00236 return "<img$id$class$ismap$usemap$title$alt src=\"$thumbURL\" width=\"" . $this->get('thumb_width')
00237 . "\" height=\"" . $this->get('thumb_height') . "\" />";
00238 case 'medium':
00239 $tmp = new SnapExternalFile($this->version, $this->get('medium'));
00240 $mediumURL = $tmp->getURL();
00241 return "<img$id$class$ismap$usemap$title$alt src=\"$mediumURL\" width=\"" . $this->get('medium_width')
00242 . "\" height=\"" . $this->get('medium_height') . "\" />";
00243 case 'display':
00244 $tmp = new SnapExternalFile($this->version, $this->get('display'));
00245 $displayURL = $tmp->getURL();
00246 return "<img$id$class$ismap$usemap$title$alt src=\"$displayURL\" width=\"" . $this->get('display_width')
00247 . "\" height=\"" . $this->get('display_height') . "\" />";
00248 default:
00249 case 'original':
00250 $tmp = new SnapExternalFile($this->version, $this->get('original'));
00251 $originalURL = $tmp->getURL();
00252 return "<img$id$class$ismap$usemap$title$alt src=\"$originalURL\" width=\"" . $this->get('original_width')
00253 . "\" height=\"" . $this->get('original_height') . "\" />";
00254 }
00255
00256 return false;
00257 }
00258
00307 public function uploadImage($tmpFile, $fileName, $options = array()) {
00308 if(!is_readable($tmpFile)) {
00309 $this->setError("File '$tmpFile' does not exist or is not accessible");
00310 return false;
00311 }
00312
00313 $info = @getimagesize($tmpFile);
00314
00315 if($info === false) {
00316 $this->setError('Invalid image: ' . $fileName);
00317 return false;
00318 }
00319
00320 list($originalWidth, $originalHeight, $type, $attr) = $info;
00321
00322 $aspect = floatval($originalWidth) / floatval($originalHeight);
00323
00324 if(isset($options['thumbScale'])) {
00325 if($options['thumbScale'] > 1.0)
00326 $options['thumbScale'] = 1.0;
00327 else if($options['thumbScale'] < 0.0)
00328 $options['thumbScale'] = 0.0;
00329 $thumbWidth = $originalWidth * $options['thumbScale'];
00330 $thumbHeight = $originalHeight * $options['thumbScale'];
00331 if(isset($options['thumbCropScale']) && $options['thumbCropScale'] == true) {
00332 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $thumbWidth, $thumbHeight);
00333 $thumbWidth = $a;
00334 $thumbHeight = $b;
00335 }
00336 }
00337 else if(isset($options['thumbSize'])) {
00338 if(!isset($options['thumbSize']['width']) || !isset($options['thumbSize']['height'])) {
00339 $this->setError('Missing "width" or "height" subattributes on "thumbSize"');
00340 return false;
00341 }
00342 $thumbWidth = $options['thumbSize']['width'];
00343 $thumbHeight = $options['thumbSize']['height'];
00344 if(isset($options['thumbCropScale']) && $options['thumbCropScale'] == true) {
00345 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $thumbWidth, $thumbHeight);
00346 $thumbWidth = $a;
00347 $thumbHeight = $b;
00348 }
00349 }
00350 else if(isset($options['thumb_resize'])) {
00351 switch($options['thumb_resize']) {
00352 case 'wide':
00353 list($thumbWidth, $thumbHeight) = $this->cropScale($originalWidth, $originalHeight, 150.0, 80.0);
00354 break;
00355 case 'square':
00356 list($thumbWidth, $thumbHeight) = $this->cropScale($originalWidth, $originalHeight, 80.0, 80.0);
00357 break;
00358 default:
00359 $this->setError("Invalid thumb "
00360 . "resizing method given: ".$options['thumb_resize']);
00361 return false;
00362 }
00363 }
00364 else {
00365 $thumbWidth = $originalWidth * 0.25;
00366 $thumbHeight = $originalHeight * 0.25;
00367 }
00368
00369 if(isset($options['mediumScale'])) {
00370 if($options['mediumScale'] > 1.0)
00371 $options['mediumScale'] = 1.0;
00372 else if($options['mediumScale'] < 0.0)
00373 $options['mediumScale'] = 0.0;
00374 $mediumWidth = $originalWidth * $options['mediumScale'];
00375 $mediumHeight = $originalHeight * $options['mediumScale'];
00376 if(isset($options['mediumCropScale']) && $options['mediumCropScale'] == true) {
00377 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $mediumWidth, $mediumHeight);
00378 $mediumWidth = $a;
00379 $mediumHeight = $b;
00380 }
00381 }
00382 else if(isset($options['mediumSize'])) {
00383 if(!isset($options['mediumSize']['width']) || !isset($options['mediumSize']['height'])) {
00384 $this->setError('Missing "width" or "height" subattributes on "mediumSize"');
00385 return false;
00386 }
00387 $mediumWidth = $options['mediumSize']['width'];
00388 $mediumHeight = $options['mediumSize']['height'];
00389 if(isset($options['mediumCropScale']) && $options['mediumCropScale'] == true) {
00390 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $mediumWidth, $mediumHeight);
00391 $mediumWidth = $a;
00392 $mediumHeight = $b;
00393 }
00394 }
00395 else if(isset($options['medium_resize'])) {
00396 switch($options['medium_resize']) {
00397 case 'standard':
00398
00399
00400 $scale = (400.0 / $originalHeight);
00401 $mediumHeight = 400.0;
00402 $mediumWidth = $scale * $originalWidth;
00403 if($mediumWidth > 5000) {
00404 $scale = (400.0 / $mediumWidth);
00405 $mediumWidth = 400.0;
00406 $mediumHeight *= $scale;
00407 }
00408 break;
00409 default:
00410 $this->setError("Invalid thumb "
00411 . "resizing method given: ".$options['thumb_resize']);
00412 return false;
00413 }
00414 }
00415 else {
00416 $mediumWidth = $originalWidth * 0.50;
00417 $mediumHeight = $originalHeight * 0.50;
00418 }
00419
00420 if(isset($options['displayScale'])) {
00421 if($options['displayScale'] > 1.0)
00422 $options['displayScale'] = 1.0;
00423 else if($options['displayScale'] < 0.0)
00424 $options['displayScale'] = 0.0;
00425 $displayWidth = $originalWidth * $options['displayScale'];
00426 $displayHeight = $originalHeight * $options['displayScale'];
00427 if(isset($options['displayCropScale']) && $options['displayCropScale'] == true) {
00428 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $displayWidth, $displayHeight);
00429 $displayWidth = $a;
00430 $displayHeight = $b;
00431 }
00432 }
00433 else if(isset($options['displaySize'])) {
00434 if(!isset($options['displaySize']['width']) || !isset($options['displaySize']['height'])) {
00435 $this->setError('Missing "width" or "height" subattributes on "displaySize"');
00436 return false;
00437 }
00438 $displayWidth = $options['displaySize']['width'];
00439 $displayHeight = $options['displaySize']['height'];
00440 if(isset($options['displayCropScale']) && $options['displayCropScale'] == true) {
00441 list($a, $b) = $this->cropScale($originalWidth, $originalHeight, $displayWidth, $displayHeight);
00442 $displayWidth = $a;
00443 $displayHeight = $b;
00444 }
00445 }
00446 else if(isset($options['display_resize'])) {
00447 switch($options['display_resize']) {
00448 case 'standard':
00449
00450
00451 $scale = (600.0 / $originalHeight);
00452 $displayHeight = 600.0;
00453 $displayWidth = $scale * $originalWidth;
00454 if($displayWidth > 5000) {
00455 $scale = (400.0 / $displayWidth);
00456 $displayWidth = 400.0;
00457 $displayHeight *= $scale;
00458 }
00459 break;
00460 default:
00461 $this->setError("Invalid thumb "
00462 . "resizing method given: ".$options['thumb_resize']);
00463 return false;
00464 }
00465 }
00466 else {
00467 $displayWidth = $originalWidth * 1.0;
00468 $displayHeight = $originalHeight * 1.0;
00469 }
00470
00471 $thumbWidth = intval($thumbWidth);
00472 $thumbHeight = intval($thumbHeight);
00473 $mediumWidth = intval($mediumWidth);
00474 $mediumHeight = intval($mediumHeight);
00475 $displayWidth = intval($displayWidth);
00476 $displayHeight = intval($displayHeight);
00477 $originalWidth = intval($originalWidth);
00478 $originalHeight = intval($originalHeight);
00479
00480 $okay = true;
00481 if($thumbWidth < 1 || $thumbWidth > 5000) {
00482 $this->setError("Thumb width is out of bounds: $thumbWidth (must be between 1 and 5000 pixels)");
00483 $okay = false;
00484 }
00485 if($mediumWidth < 1 || $mediumWidth > 5000) {
00486 $this->setError("Medium width is out of bounds: $mediumWidth (must be between 1 and 5000 pixels)");
00487 $okay = false;
00488 }
00489 if($displayWidth < 1 || $displayWidth > 5000) {
00490 $this->setError("Display width is out of bounds: $displayWidth (must be between 1 and 5000 pixels)");
00491 $okay = false;
00492 }
00493 if($thumbHeight < 1 || $thumbHeight > 5000) {
00494 $this->setError("Thumb height is out of bounds: $thumbHeight (must be between 1 and 5000 pixels)");
00495 $okay = false;
00496 }
00497 if($mediumHeight < 1 || $mediumHeight > 5000) {
00498 $this->setError("Medium height is out of bounds: $mediumHeight (must be between 1 and 5000 pixels)");
00499 $okay = false;
00500 }
00501 if($displayHeight < 1 || $displayHeight > 5000) {
00502 $this->setError("Display height is out of bounds: $displayHeight (must be between 1 and 5000 pixels)");
00503 $okay = false;
00504 }
00505 if(!$okay)
00506 return false;
00507
00508 $new_thumb = tempnam("/tmp", "thumb");
00509 $new_medium = tempnam("/tmp", "medium");
00510 $new_display = tempnam("/tmp", "display");
00511 if($new_thumb == "" || $new_medium == "" || $new_display == "") {
00512 $this->setError("Error creating files");
00513 return false;
00514 }
00515
00516
00517
00518 $origImage = imagecreatefromstring(file_get_contents($tmpFile));
00519 if($origImage === false) {
00520 $this->setError('Failed to create image in memory');
00521 unlink($new_thumb);
00522 unlink($new_medium);
00523 unlink($new_display);
00524 return false;
00525 }
00526
00527 system("convert \"$tmpFile\" -resize ${thumbWidth}x$thumbHeight $new_thumb");
00528 system("convert \"$tmpFile\" -resize ${mediumWidth}x$mediumHeight $new_medium");
00529 system("convert \"$tmpFile\" -resize ${displayWidth}x$displayHeight $new_display");
00530
00531 if($type == IMAGETYPE_JPEG)
00532 $format = "jpeg";
00533 else if($type == IMAGETYPE_GIF)
00534 $format = "gif";
00535 else
00536 $format = "png";
00537
00538 $thumbFile = new SnapExternalFile($this->version);
00539 $mediumFile = new SnapExternalFile($this->version);
00540 $displayFile = new SnapExternalFile($this->version);
00541 $originalFile = new SnapExternalFile($this->version);
00542
00543 $thumbFile->create($new_thumb, $fileName);
00544 $mediumFile->create($new_medium, $fileName);
00545 $displayFile->create($new_display, $fileName);
00546 $originalFile->create($tmpFile, $fileName);
00547
00548 unlink($new_thumb);
00549 unlink($new_medium);
00550 unlink($new_display);
00551
00552 $this->set('thumb', $thumbFile->getArray());
00553 $this->set('medium', $mediumFile->getArray());
00554 $this->set('display', $displayFile->getArray());
00555 $this->set('original', $originalFile->getArray());
00556 $this->set('format', $format);
00557 $this->set('original_name', $fileName);
00558
00559 $this->set('original_width', $originalWidth);
00560 $this->set('original_height', $originalHeight);
00561 $this->set('thumb_width', $thumbWidth);
00562 $this->set('thumb_height', $thumbHeight);
00563 $this->set('medium_width', $mediumWidth);
00564 $this->set('medium_height', $mediumHeight);
00565 $this->set('display_width', $displayWidth);
00566 $this->set('display_height', $displayHeight);
00567
00568 $this->set('config', $options);
00569
00570 return true;
00571 }
00572
00584 private function cropScale($originalWidth, $originalHeight, $newWidth, $newHeight) {
00585 $aspect = floatval($originalWidth) / floatval($originalHeight);
00586 if($aspect < ($newWidth / $newHeight)) {
00587 $scale = ($newWidth / $originalHeight);
00588 $width = $newWidth;
00589 $height = $originalWidth * $scale;
00590 }
00591 else if($aspect > ($newWidth / $newHeight)) {
00592 $scale = ($newHeight / $originalWidth);
00593 $width = $newWidth;
00594 $height = $originalHeight * $scale;
00595 }
00596 else {
00597 $width = $newWidth;
00598 $height = $newHeight;
00599 }
00600 return array($width, $height);
00601 }
00602
00618 public function rescaleImages($oldCM, $options = array()) {
00619 $tmpFile = $oldCM->getPath();
00620 $fileName = $oldCM->getImageName();
00621
00622 return $this->uploadImage($tmpFile, $fileName, $options);
00623 }
00624
00632 public function getImageName() {
00633 if(!$this->validate())
00634 return false;
00635
00636 return $this->get('original_name');
00637 }
00638
00646 public function getConfig() {
00647 if(!$this->validate())
00648 return false;
00649
00650 if($this->get('config') !== null)
00651 return $this->get('config');
00652 else
00653 return array(
00654 'thumbSize' => array(
00655 'width' => $this->get('thumb_width'),
00656 'height' => $this->get('thumb_height')
00657 ),
00658 'mediumSize' => array(
00659 'width' => $this->get('medium_width'),
00660 'height' => $this->get('medium_height')
00661 ),
00662 'displaySize' => array(
00663 'width' => $this->get('display_width'),
00664 'height' => $this->get('display_height')
00665 )
00666 );
00667 }
00668
00677 public function getURL($which = 'original') {
00678 if(!$this->validate())
00679 return false;
00680
00681 $which = strtolower($which);
00682 if($which != 'original' && $which != 'thumb'
00683 && $which != 'medium' && $which != 'display')
00684 $which = 'original';
00685
00686 $fl = new SnapExternalFile($this->version, $this->get($which));
00687 return $fl->getURL();
00688 }
00689
00698 public function getPath($which = 'original') {
00699 if(!$this->validate())
00700 return false;
00701
00702 $which = strtolower($which);
00703 if($which != 'original' && $which != 'thumb'
00704 && $which != 'medium' && $which != 'display')
00705 $which = 'original';
00706
00707 $fl = new SnapExternalFile($this->version, $this->get($which));
00708 return $fl->getPath();
00709
00710 }
00711
00718 public function getWidth($which = 'original') {
00719 if(!$this->validate())
00720 return false;
00721
00722 $which = strtolower($which);
00723 if($which != 'original' && $which != 'thumb'
00724 && $which != 'medium' && $which != 'display')
00725 $which = 'original';
00726
00727 return $this->get("{$which}_width");
00728 }
00729
00736 public function getHeight($which = 'original') {
00737 if(!$this->validate())
00738 return false;
00739
00740 $which = strtolower($which);
00741 if($which != 'original' && $which != 'thumb'
00742 && $which != 'medium' && $which != 'display')
00743 $which = 'original';
00744
00745 return $this->get("{$which}_height");
00746 }
00747
00754 public function getFormat() {
00755 if(!$this->validate())
00756 return false;
00757
00758 return $this->get('format');
00759 }
00760
00769 public function getSize($which = 'original') {
00770 if(!$this->validate())
00771 return false;
00772 if($which != 'original' && $which != 'thumb' && $which != 'medium' && $which != 'display')
00773 $which = 'original';
00774 $file = new SnapExternalFile($this->version, $this->get($which));
00775 return filesize($file->getPath());
00776 }
00777
00786 public function setOptions($options) {
00787 if(!$this->validate())
00788 return false;
00789 $this->set('options', $options);
00790 }
00791
00799 public function getOptions() {
00800 $options = $this->get('options');
00801 if(!$options)
00802 $options = array();
00803 return $options;
00804 }
00805
00813 public function checkMedia() {
00814
00815 if($this->get('thumb') == '')
00816 return true;
00817
00818 if(!$this->validate())
00819 return false;
00820
00821 $thumb = new SnapExternalFile($this->version, $this->get('thumb'));
00822 $medium = new SnapExternalFile($this->version, $this->get('medium'));
00823 $display = new SnapExternalFile($this->version, $this->get('display'));
00824 $original = new SnapExternalFile($this->version, $this->get('original'));
00825
00826 $path = $thumb->getPath();
00827 if($path != '' && (!is_readable($path) || !is_file($path)))
00828 return false;
00829 $path = $medium->getPath();
00830 if($path != '' && (!is_readable($path) || !is_file($path)))
00831 return false;
00832 $path = $display->getPath();
00833 if($path != '' && (!is_readable($path) || !is_file($path)))
00834 return false;
00835 $path = $original->getPath();
00836 if($path != '' && (!is_readable($path) || !is_file($path)))
00837 return false;
00838
00839 return true;
00840 }
00841
00849 public function updateFileList() {
00850 if(!$this->validate())
00851 return 'no files to insert';
00852 SnapDBI::startTransaction();
00853 $thumb = new SnapExternalFile($this->version, $this->get('thumb'));
00854 $medium = new SnapExternalFile($this->version, $this->get('medium'));
00855 $display = new SnapExternalFile($this->version, $this->get('display'));
00856 $original = new SnapExternalFile($this->version, $this->get('original'));
00857
00858 if(!$thumb->updateDB() || !$medium->updateDB() || !$display->updateDB() || !$original->updateDB()) {
00859 SnapDBI::cancelTransaction();
00860 return 'database failure';
00861 }
00862 else {
00863 SnapDBI::commitTransaction();
00864 return true;
00865 }
00866 }
00867 }
00868
00869 ?>