Changeset 2134
- Timestamp:
- 09/03/10 16:43:34 (21 months ago)
- Location:
- plugins/apostrophePlugin/trunk
- Files:
-
- 12 added
- 4 removed
- 21 modified
- 4 moved
-
. (modified) (1 prop)
-
README (modified) (1 diff)
-
lib/action/BaseaMediaActions.class.php (modified) (12 diffs)
-
lib/action/BaseaMediaBackendActions.class.php (modified) (4 diffs)
-
lib/form/BaseaMediaEditForm.class.php (added)
-
lib/form/BaseaMediaEditMultipleForm.class.php (added)
-
lib/form/BaseaMediaImageForm.class.php (modified) (1 diff)
-
lib/form/BaseaMediaUploadForm.class.php (added)
-
lib/form/BaseaMediaUploadMultipleForm.class.php (added)
-
lib/form/aMediaEditForm.class.php (added)
-
lib/form/aMediaEditMultipleForm.class.php (added)
-
lib/form/aMediaUploadForm.class.php (added)
-
lib/form/aMediaUploadMultipleForm.class.php (added)
-
lib/helper/aHelper.php (modified) (1 diff)
-
lib/model/doctrine/PluginaMediaItem.class.php (modified) (3 diffs)
-
lib/model/doctrine/PluginaMediaItemTable.class.php (modified) (2 diffs)
-
lib/model/doctrine/PluginaPage.class.php.orig (added)
-
lib/toolkit/BaseaTools.class.php (modified) (4 diffs)
-
lib/toolkit/aImageConverter.class.php (modified) (4 diffs)
-
lib/toolkit/aMediaRouting.php (modified) (1 diff)
-
lib/toolkit/aMediaTools.php (modified) (6 diffs)
-
lib/validator/aValidatedFile.class.php (added)
-
lib/validator/aValidatorFilePersistent.class.php (modified) (7 diffs)
-
lib/widget/aWidgetFormInputFilePersistent.class.php (modified) (3 diffs)
-
modules/aMedia/templates/_browser.php (modified) (1 diff)
-
modules/aMedia/templates/_edit.php (moved) (moved from plugins/apostrophePlugin/trunk/modules/aMedia/templates/_editImage.php) (3 diffs)
-
modules/aMedia/templates/_editLinks.php (modified) (1 diff)
-
modules/aMedia/templates/_mediaItem.php (modified) (3 diffs)
-
modules/aMedia/templates/_upload.php (moved) (moved from plugins/apostrophePlugin/trunk/modules/aMedia/templates/_uploadImage.php)
-
modules/aMedia/templates/editMultipleSuccess.php (moved) (moved from plugins/apostrophePlugin/trunk/modules/aMedia/templates/editImagesSuccess.php) (4 diffs)
-
modules/aMedia/templates/editPdfSuccess.php (deleted)
-
modules/aMedia/templates/editSuccess.php (moved) (moved from plugins/apostrophePlugin/trunk/modules/aMedia/templates/editImageSuccess.php) (1 diff)
-
modules/aMedia/templates/indexSuccess.php (modified) (1 diff)
-
modules/aMedia/templates/updateMultiplePreviewSuccess.php (deleted)
-
modules/aMedia/templates/uploadImagesRedirect.php (deleted)
-
modules/aMedia/templates/uploadImagesSuccess.php (deleted)
-
modules/aMedia/templates/uploadSuccess.php (added)
-
web/css/a.css (modified) (1 prop)
-
web/images (modified) (1 prop)
-
web/images/a-icons-format-pdf.png (added)
-
web/js/a.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
plugins/apostrophePlugin/trunk
- Property svn:mergeinfo changed
/plugins/apostrophePlugin/branches/1.4 merged: 2093,2103
- Property svn:mergeinfo changed
-
plugins/apostrophePlugin/trunk/README
r457 r2134 1 1 # Apostrophe 2 2 3 Welcome to the 1.0 stable release of Apostrophe! Although this is our first official stable release, our CMS is already in regular use on a number of production sites. This release reflects the fact that our code has been stable and ready for your professional use for quite some time.3 Welcome to Apostrophe! 4 4 5 5 For complete and extensive documentation of Apostrophe please visit -
plugins/apostrophePlugin/trunk/lib/action/BaseaMediaActions.class.php
r1957 r2134 59 59 $tag = $request->getParameter('tag'); 60 60 $type = $request->getParameter('type'); 61 $typeInfos = aMediaTools::getTypeInfos($type); 62 $this->embedAllowed = false; 63 $this->uploadAllowed = false; 64 foreach ($typeInfos as $typeInfo) 65 { 66 if ($typeInfo['embeddable']) 67 { 68 $this->embedAllowed = true; 69 } 70 if (count($typeInfo['extensions'])) 71 { 72 $this->uploadAllowed = true; 73 } 74 } 61 75 $category = $request->getParameter('category'); 62 76 if (aMediaTools::getType()) … … 409 423 } 410 424 411 public function executeEdit Image(sfRequest $request)425 public function executeEdit(sfRequest $request) 412 426 { 413 427 $this->forward404Unless(aMediaTools::userHasUploadPrivilege()); … … 424 438 } 425 439 $this->item = $item; 426 $this->form = new aMedia ImageForm($item);440 $this->form = new aMediaEditForm($item); 427 441 if ($request->isMethod('post')) 428 442 { 429 $this->firstPass = $request->getParameter('first_pass');430 443 $parameters = $request->getParameter('a_media_item'); 431 444 $files = $request->getFiles('a_media_item'); … … 444 457 // Everything except the actual copy which can't succeed 445 458 // until the slug is cast in stone 446 $object->preSave Image($file->getTempName());459 $object->preSaveFile($file->getTempName()); 447 460 } 448 461 $this->form->save(); 449 462 if ($file) 450 463 { 451 $object->save Image($file->getTempName());464 $object->saveFile($file->getTempName()); 452 465 } 453 466 return $this->redirect("aMedia/resumeWithPage"); 454 467 } 455 }456 }457 458 public function executeEditPdf(sfRequest $request)459 {460 $this->forward404Unless(aMediaTools::userHasUploadPrivilege());461 $item = null;462 $this->slug = false;463 if ($request->hasParameter('slug'))464 {465 $item = $this->getItem();466 $this->slug = $item->getSlug();467 }468 if ($item)469 {470 $this->forward404Unless($item->userHasPrivilege('edit'));471 }472 $this->item = $item;473 $this->form = new aMediaPdfForm($item);474 try475 {476 if ($request->isMethod('post'))477 {478 $this->firstPass = $request->getParameter('first_pass');479 $parameters = $request->getParameter('a_media_item');480 $files = $request->getFiles('a_media_item');481 $this->form->bind($parameters, $files);482 if ($this->form->isValid())483 {484 $file = $this->form->getValue('file');485 $object = $this->form->getObject();486 if ($file)487 {488 // This actually has to be shimmed in at a much lower level as an option if489 // gs is not available. We can't just use a fake thumbnail as an 'original' as we490 // do for foreign video because that would break 'download original'491 // copy(sfConfig::get('sf_root_dir') . '/plugins/apostrophePlugin/web/images/a-media-pdf-btn-small.png', $previewFile);492 493 // Everything except the actual copy which can't succeed494 // until the slug is cast in stone495 if (!$object->preSaveImage($file->getTempName()))496 {497 // Ideally this doesn't happen, in practice sometimes a PDF has498 // a good signature but bad content or ghostscript hates it499 throw new sfException('Defective PDF file');500 }501 }502 // The base implementation for saving files gets confused when503 // $file is not set, a situation that our code tolerates as useful504 // because if you're updating a record containing a PDF you505 // often don't need to submit a new one.506 unset($this->form['file']);507 $this->form->save();508 if ($file)509 {510 $object->saveImage($file->getTempName());511 }512 return $this->redirect("aMedia/resumeWithPage");513 }514 }515 } catch (Exception $e)516 {517 $this->serviceError = $e->getMessage();518 // TODO make this visible somehow519 468 } 520 469 } … … 577 526 if ($thumbnail) 578 527 { 579 $object->preSave Image($thumbnail->getTempName());528 $object->preSaveFile($thumbnail->getTempName()); 580 529 } 581 530 $this->form->save(); 582 531 if ($thumbnail) 583 532 { 584 $object->save Image($thumbnail->getTempName());533 $object->saveFile($thumbnail->getTempName()); 585 534 } 586 535 } … … 644 593 $object = $this->form->getObject(); 645 594 $new = !$object->getId(); 646 $object->preSave Image($thumbnailCopy);595 $object->preSaveFile($thumbnailCopy); 647 596 $object->setServiceUrl($url); 648 597 $this->form->save(); 649 $object->save Image($thumbnailCopy);598 $object->saveFile($thumbnailCopy); 650 599 unlink($thumbnailCopy); 651 600 } … … 655 604 } 656 605 657 public function executeUpload Images(sfRequest $request)606 public function executeUpload(sfRequest $request) 658 607 { 659 608 // Belongs at the beginning, not the end 660 609 $this->forward404Unless(aMediaTools::userHasUploadPrivilege()); 661 $this->form = new aMediaUpload ImagesForm();610 $this->form = new aMediaUploadMultipleForm(); 662 611 if ($request->isMethod('post')) 663 612 { … … 668 617 { 669 618 $request->setParameter('first_pass', true); 670 $active = array();671 619 // Saving embedded forms is weird. We can get the form objects 672 620 // via getEmbeddedForms(), but those objects were never really … … 676 624 // See: 677 625 // http://thatsquality.com/articles/can-the-symfony-forms-framework-be-domesticated-a-simple-todo-list 626 $items = $request->getParameter("a_media_items"); 678 627 for ($i = 0; ($i < aMediaTools::getOption('batch_max')); $i++) 679 628 { 680 629 $values = $this->form->getValues(); 681 if ($values["item-$i"]['file']) 682 { 683 $active[] = $i; 630 $file = $values["item-$i"]['file']; 631 if ($file) 632 { 633 // Humanize the original filename 634 $title = $file->getOriginalName(); 635 $title = preg_replace('/\.\w+$/', '', $title); 636 $title = aTools::slugify($title, false, false, ' '); 637 $items["item-$i"]['title'] = $title; 684 638 } 685 639 else 686 640 { 687 641 // So the editImagesForm validator won't complain about these 688 $items = $request->getParameter("a_media_items");689 642 unset($items["item-$i"]); 690 $request->setParameter("a_media_items", $items);691 643 } 692 644 } 693 $request->setParameter('active', implode(",", $active)); 694 // We'd like to just do this... 695 // $this->forward('aMedia', 'editImages'); 696 // But we need to break out of the iframe, and 697 // modern browsers ignore Window-target: _top which 698 // would otherwise be perfect for this. 699 // Fortunately, the persistent file upload widget can tolerate 700 // a GET-method redirect very nicely as long as we pass the 701 // persistids. So we make the current parameters available 702 // to a template that breaks out of the iframe via 703 // JavaScript and passes the prameters on. 704 $this->parameters = $request->getParameterHolder('a_media_items')->getAll(); 705 // If I don't do this I just get redirected back to myself 706 unset($this->parameters['module']); 707 unset($this->parameters['action']); 708 return 'Redirect'; 709 } 710 } 711 } 712 713 public function executeEditImages(sfRequest $request) 645 $request->setParameter("a_media_items", $items); 646 // We're not doing stupid iframe tricks anymore, so we can just forward 647 $this->forward('aMedia', 'editMultiple'); 648 // 649 // // We'd like to just do this... 650 // // $this->forward('aMedia', 'edit'); 651 // // But we need to break out of the iframe, and 652 // // modern browsers ignore Window-target: _top which 653 // // would otherwise be perfect for this. 654 // // Fortunately, the persistent file upload widget can tolerate 655 // // a GET-method redirect very nicely as long as we pass the 656 // // persistids. So we make the current parameters available 657 // // to a template that breaks out of the iframe via 658 // // JavaScript and passes the prameters on. 659 // $this->parameters = $request->getParameterHolder('a_media_items')->getAll(); 660 // // If I don't do this I just get redirected back to myself 661 // unset($this->parameters['module']); 662 // unset($this->parameters['action']); 663 // return 'Redirect'; 664 } 665 } 666 } 667 668 public function executeEditMultiple(sfRequest $request) 714 669 { 715 670 $this->forward404Unless(aMediaTools::userHasUploadPrivilege()); … … 722 677 // single HTML form element. 723 678 $this->firstPass = $request->getParameter('first_pass'); 724 $active = $request->getParameter('active'); 725 $this->forward404Unless(preg_match("/^\d+[\d\,]*$/", $active)); 726 $this->active = explode(",", $request->getParameter('active')); 727 728 $this->form = new aMediaEditImagesForm($this->active); 679 $items = $request->getParameter('a_media_items'); 680 // The active parameter was redundant, just look at the items that are present. 681 // This allows successive passes to prune out some items if desired 682 $active = array(); 683 foreach ($items as $itemName => $item) 684 { 685 if (preg_match('/^item-(\d+)$/', $itemName, $matches)) 686 { 687 $active[] = $matches[1]; 688 } 689 } 690 691 $this->form = new aMediaEditMultipleForm($active); 729 692 $this->form->bind( 730 693 $request->getParameter('a_media_items'), 731 694 $request->getFiles('a_media_items')); 732 if ( $this->form->isValid())695 if ((!$this->firstPass) && $this->form->isValid()) 733 696 { 734 697 $values = $this->form->getValues(); … … 756 719 // until the slug is cast in stone 757 720 $file = $values[$key]['file']; 758 $object->preSaveImage($file->getTempName()); 721 722 $format = $file->getExtension(); 723 if (strlen($format)) 724 { 725 // Starts with a . 726 $format = substr($format, 1); 727 } 728 $object->format = $format; 729 $types = aMediaTools::getOption('types'); 730 foreach ($types as $type => $info) 731 { 732 $extensions = $info['extensions']; 733 if (in_array($format, $extensions)) 734 { 735 $object->type = $type; 736 } 737 } 738 $object->preSaveFile($file->getTempName()); 759 739 $object->save(); 760 $object->save Image($file->getTempName());740 $object->saveFile($file->getTempName()); 761 741 } 762 742 return $this->redirect('aMedia/resume'); … … 764 744 } 765 745 746 public function executeEmbed() 747 { 748 // TODO: rework this to be less video-oriented 749 return $this->redirect('aMedia/newVideo'); 750 } 751 766 752 public function executeDelete() 767 753 { -
plugins/apostrophePlugin/trunk/lib/action/BaseaMediaBackendActions.class.php
r1917 r2134 11 11 $item = $this->getItem(); 12 12 $format = $request->getParameter('format'); 13 $this->forward404Unless( 14 in_array($format, 15 array_keys(aMediaItemTable::$mimeTypes))); 13 $mimeTypes = aMediaTools::getOption('mime_types'); 14 $this->forward404Unless(isset($mimeTypes[$format])); 16 15 $path = $item->getOriginalPath($format); 17 16 if (!file_exists($path)) … … 21 20 $item->getOriginalPath($format)); 22 21 } 23 header("Content-type: " . aMediaItemTable::$mimeTypes[$format]);22 header("Content-type: " . $mimeTypes[$format]); 24 23 readfile($item->getOriginalPath($format)); 25 24 // Don't let the binary get decorated with crap … … 35 34 $resizeType = $request->getParameter('resizeType'); 36 35 $format = $request->getParameter('format'); 37 $this->forward404Unless( 38 in_array($format, 39 array_keys(aMediaItemTable::$mimeTypes))); 36 $mimeTypes = aMediaTools::getOption('mime_types'); 37 $this->forward404Unless(isset($mimeTypes[$format])); 40 38 $this->forward404Unless(($resizeType !== 'c') || ($resizeType !== 's')); 41 39 // EDITED FOR ARBITRARY CROPPING … … 105 103 // PHP interpreter hit to consider, so use those directives! 106 104 header("Content-length: " . filesize($output)); 107 header("Content-type: " . aMediaItemTable::$mimeTypes[$format]);105 header("Content-type: " . $mimeTypes[$format]); 108 106 readfile($output); 109 107 // If I don't bail out manually here I get PHP warnings, -
plugins/apostrophePlugin/trunk/lib/form/BaseaMediaImageForm.class.php
r1697 r2134 23 23 24 24 $this->setWidget('file', new aWidgetFormInputFilePersistent(array( 25 // Not yet26 // "iframe" => true,27 // "progress" => "Uploading...",28 25 'image-preview' => aMediaTools::getOption('gallery_constraints') 29 26 ))); -
plugins/apostrophePlugin/trunk/lib/helper/aHelper.php
r2076 r2134 447 447 { 448 448 $args = array_slice(func_get_args(), 1); 449 450 449 a_js_call_array($callable, $args); 451 450 } -
plugins/apostrophePlugin/trunk/lib/model/doctrine/PluginaMediaItem.class.php
r1935 r2134 108 108 } 109 109 110 public function preSave Image($file)110 public function preSaveFile($file) 111 111 { 112 112 // Refactored into aImageConverter for easier reuse of this should-be-in-PHP functionality … … 123 123 $this->height = $info['height']; 124 124 } 125 $this->format = $info['format']; 125 // Don't force this, but it's useful when we're not 126 // coming from a normal upload form 127 if (!isset($file->format)) 128 { 129 $this->format = $info['format']; 130 } 126 131 $this->clearImageCache(true); 127 return true; 128 } 129 else 130 { 131 return false; 132 } 133 } 134 135 public function saveImage($file) 132 } 133 } 134 135 public function saveFile($file) 136 136 { 137 137 if (!$this->width) 138 138 { 139 if (!$this->preSave Image($file))139 if (!$this->preSaveFile($file)) 140 140 { 141 141 return false; … … 369 369 return $this->getTable()->findOneBySlug($p[0]); 370 370 } 371 372 public function getDownloadable() 373 { 374 // Right now videos are always embedded and nothing else is 375 return ($this->type !== 'video'); 376 } 377 378 public function getEmbeddable() 379 { 380 // Right now videos are always embedded and nothing else is 381 return ($this->type === 'video'); 382 } 371 383 } -
plugins/apostrophePlugin/trunk/lib/model/doctrine/PluginaMediaItemTable.class.php
r1917 r2134 67 67 return $q->execute(); 68 68 } 69 static public $mimeTypes = array(70 "gif" => "image/gif",71 "png" => "image/png",72 "jpg" => "image/jpeg",73 "pdf" => "application/pdf"74 );75 69 76 70 // Returns a query matching media items satisfying the specified parameters, all of which … … 79 73 // tag 80 74 // search 81 // type (video or image)75 // type (video, image, etc) 82 76 // user (a username, to determine access rights) 83 77 // aspect-width and aspect-height (returns only images with the specified aspect ratio) -
plugins/apostrophePlugin/trunk/lib/toolkit/BaseaTools.class.php
r2030 r2134 688 688 // trailing -'s are removed 689 689 690 static public function slugify($path, $allowSlashes = false) 690 // $betweenWords must not contain characters that have special meaning in a regexp. 691 // Usually it is - (the default) or ' ' 692 693 static public function slugify($path, $allowSlashes = false, $allowUnderscores = true, $betweenWords = '-') 691 694 { 692 695 // This is the inverse of the method above … … 694 697 { 695 698 // UTF-8 capable replacement for \W. Works fine for English and also for Greek, etc. 696 $alnum = '\p{L}\p{N} _';699 $alnum = '\p{L}\p{N}' . ($allowUnderscores ? '_' : ''); 697 700 $modifier = 'u'; 698 701 } 699 702 else 700 703 { 701 $alnum = '\w';704 $alnum = $allowUnderscores ? '\w' : '[A-Za-z0-9]'; 702 705 $modifier = ''; 703 706 } … … 706 709 $alnum .= '\/'; 707 710 } 708 $regexp = "/[^$alnum\-]+/$modifier"; 709 $path = aTools::strtolower(preg_replace("/[^$alnum\-]+/$modifier", '-', $path)); 711 // Removing - here expands flexibility and shouldn't hurt because it's the replacement anyway 712 $regexp = "/[^$alnum]+/$modifier"; 713 $path = aTools::strtolower(preg_replace($regexp, $betweenWords, $path)); 710 714 if ($allowSlashes) 711 715 { … … 716 720 } 717 721 // No consecutive dashes 718 $path = preg_replace("/ -+/$modifier", '-', $path);722 $path = preg_replace("/$betweenWords+/$modifier", $betweenWords, $path); 719 723 // Leading and trailing dashes are silly. This has the effect of trim() 720 724 // among other sensible things -
plugins/apostrophePlugin/trunk/lib/toolkit/aImageConverter.class.php
r1917 r2134 258 258 static private function scaleGd($fileIn, $fileOut, $scaleParameters = array(), $cropParameters = array(), $quality = 75) 259 259 { 260 260 261 // gd version for those who can't install netpbm, poor buggers 261 262 // "handles" PDF by rendering a blank white image. We already superimpose a PDF icon, … … 295 296 { 296 297 $in = self::imagecreatefromany($fileIn); 298 } 299 300 if (!$in) 301 { 302 return false; 297 303 } 298 304 … … 453 459 // If the file does not have a valid header identifying it as one of these types, false is returned. 454 460 455 static public function getInfo($file) 456 { 461 // If the 'format-only' option is true, only the format field is returned. This is much faster if the 462 // file is a PDF. 463 464 static public function getInfo($file, $options = array()) 465 { 466 $formatOnly = (isset($options['format-only']) && $options['format-only']); 457 467 $result = array(); 458 468 $in = fopen($file, "rb"); 459 469 $data = fread($in, 4); 460 470 fclose($in); 471 472 461 473 if ($data === '%PDF') 462 474 { 463 if (!aImageConverter::supportsInput('pdf')) 475 // format-only 476 if ((!aImageConverter::supportsInput('pdf')) || $formatOnly) 464 477 { 465 478 // All we can do is confirm the format and allow … … 528 541 } 529 542 $format = $formats[$data[2]]; 543 $result['format'] = $format; 544 if ($formatOnly) 545 { 546 return $result; 547 } 530 548 $result['width'] = $data[0]; 531 549 $result['height'] = $data[1]; 532 $result['format'] = $format;533 550 return $result; 534 551 } -
plugins/apostrophePlugin/trunk/lib/toolkit/aMediaRouting.php
r1917 r2134 102 102 ))); 103 103 104 $r->prependRoute('a_media_upload _images', new aRoute('/uploadImages', array(104 $r->prependRoute('a_media_upload', new aRoute('/upload', array( 105 105 'module' => 'aMedia', 106 'action' => 'upload Images'106 'action' => 'upload' 107 107 ))); 108 108 109 $r->prependRoute('a_media_edit_ images', new aRoute('/editImages', array(109 $r->prependRoute('a_media_edit_multiple', new aRoute('/editMultiple', array( 110 110 'module' => 'aMedia', 111 'action' => 'editImages' 111 'action' => 'editMultiple' 112 ))); 113 114 $r->prependRoute('a_media_edit', new aRoute('/edit', array( 115 'module' => 'aMedia', 116 'action' => 'edit' 112 117 ))); 113 118 -
plugins/apostrophePlugin/trunk/lib/toolkit/aMediaTools.php
r2022 r2134 106 106 return self::getAttribute('type'); 107 107 } 108 109 static public function getBestTypeLabel() 110 { 111 $type = aMediaTools::getType(); 112 if ($type) 113 { 114 $typeInfo = aMediaTools::getTypeInfo($type); 115 return $typeInfo['label']; 116 } 117 else 118 { 119 return 'Media'; 120 } 121 } 108 122 109 123 static public function userHasUploadPrivilege() … … 129 143 return sfContext::getInstance()->getUser(); 130 144 } 131 // Symfony 1.2 has no namespaces for attributes for some reason 145 132 146 static public function getAttribute($attribute, $default = null) 133 147 { 148 // If you are logged out, you should have no attributes, as 149 // all attributes used in the media engine relate to selection 150 if (!self::getUser()->isAuthenticated()) 151 { 152 return $default; 153 } 134 154 $attribute = "aMedia-$attribute"; 135 155 return self::getUser()->getAttribute($attribute, $default, 'apostrophe_media'); 136 156 } 157 137 158 static public function setAttribute($attribute, $value = null) 138 159 { … … 140 161 self::getUser()->setAttribute($attribute, $value, 'apostrophe_media'); 141 162 } 163 142 164 static public function removeAttributes() 143 165 { … … 145 167 $user->getAttributeHolder()->removeNamespace('apostrophe_media'); 146 168 } 169 147 170 // This is a good convention for plugin options IMHO 148 171 static private $options = array( … … 174 197 'apipublic' => false, 175 198 'embed_codes' => false, 176 'apikeys' => array() 177 ); 199 'apikeys' => array(), 200 201 // All mime types that are acceptable for upload to the media repository, 202 // keyed by the file extensions we save them under (regardless of the original name) 203 204 'mime_types' => array( 205 "gif" => "image/gif", 206 "png" => "image/png", 207 "jpg" => "image/jpeg", 208 "pdf" => "application/pdf", 209 "mp3" => "mpeg/mp3", 210 'xls' => 'application/vnd.ms-excel', 211 'ppt' => 'application/vnd.ms-powerpoint', 212 'doc' => 'application/msword', 213 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 214 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 215 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 216 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 217 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 218 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 219 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 220 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 221 'txt' => 'text/plain', 222 'rtf' => 'text/rtf' 223 ), 224 225 // You can override these to add more types to the system. These are the 226 // major types one can filter by in the media repository. Adding something here 227 // doesn't necessarily mean browsers can display it or our slots are designed 228 // to render it, in particular don't add new audio formats to 'audio' without 229 // overriding our audio slots to play them (and keep in mind the browser probably 230 // knows nothing about them) 231 232 // Video has no extensions because we don't provide processing of video uploads, 233 // which are in a dizzying array of formats most browsers won't play. That's why 234 // YouTube exists. Videos are brought into the system via "Embed Media," not "Upload Media" 235 236 // Typically the only section you'll override here is 'file'. You can add more 237 // accepted extensions and/or break it up into 'Office' and 'Other' etc 238 239 // Also see 'getDownloadable' and 'getEmbeddable' in aMediaItem 240 241 'types' => array( 242 'image' => array('label' => 'Image', 'extensions' => array('gif', 'png', 'jpg'), 'embeddable' => false), 243 'pdf' => array('label' => 'PDF', 'extensions' => array('pdf'), 'embeddable' => false), 244 'audio' => array('label' => 'Audio', 'extensions' => array('mp3'), 'embeddable' => false), 245 'video' => array('label' => 'Video', 'extensions' => array(), 'embeddable' => true), 246 247 // A long whitelist of file formats that are usually benign and useful. 248 // No .exe, no .zip. You can add them via app.yml if you really want them. 249 // We list only the non-macro-enabled Microsoft extensions in an effort to 250 // honor their good-faith attempt to label more dangerous files 251 252 'office' => array('label' => 'Office', 'extensions' => array('txt', 'rtf', 'csv', 'doc', 'docx', 'xls', 'xlsx', 'xlsb', 'ppt', 'pptx', 'ppsx'), 'embeddable' => false))); 253 178 254 static public function getOption($name) 179 255 { … … 188 264 throw new Exception("Unknown option in apostrophePlugin: $name"); 189 265 } 266 } 267 268 static public function getTypeInfo($name) 269 { 270 $types = aMediaTools::getOption('types'); 271 return $types[$name]; 272 } 273 274 // Returns an array of type infos, just the one if you specify a type, all if you don't. 275 // Handy when filtering 276 static public function getTypeInfos($type = null) 277 { 278 $types = aMediaTools::getOption('types'); 279 if (is_null($type)) 280 { 281 return $types; 282 } 283 return array($types[$type]); 190 284 } 191 285 -
plugins/apostrophePlugin/trunk/lib/validator/aValidatorFilePersistent.class.php
r1957 r2134 17 17 class aValidatorFilePersistent extends sfValidatorFile 18 18 { 19 // Make the original name available to guessers. It's a nice thought to 20 // avoid this but with Microsoft Office formats there are no reliable 21 // magic numbers, and those that do exist can be misleading because 22 // Word can contain Excel and vice versa 23 protected $originalName; 19 24 20 25 protected function configure($options = array(), $messages = array()) … … 31 36 array_unshift($mimeTypeGuessers, array($this, 'guessFromImageconverter')); 32 37 array_unshift($mimeTypeGuessers, array($this, 'guessFromID3')); 38 array_unshift($mimeTypeGuessers, array($this, 'guessRTF')); 33 39 $this->setOption('mime_type_guessers', $mimeTypeGuessers); 34 40 } … … 123 129 $cvalue = $value['newfile']; 124 130 } 125 // This will throw an exception if there is a validation error. 126 // That's a good thing: we don't want to save it for reuse 127 // in that situation. 131 $this->originalName = $cvalue['name']; 128 132 try 129 133 { … … 155 159 $data['newfile'] = true; 156 160 $data['tmp_name'] = $filePath; 161 162 // It's useful to know the mime type and true extension for 163 // supplying previews and icons 164 $extensionsByMimeType = array_flip(aMediaTools::getOption('mime_types')); 165 $data['mime_type'] = $this->getMimeType($filePath, $cvalue['type']); 166 if (isset($extensionsByMimeType[$data['mime_type']])) 167 { 168 $data['extension'] = $extensionsByMimeType[$data['mime_type']]; 169 } 170 157 171 self::putFileInfo($persistid, $data); 158 172 } … … 197 211 $persistid = $value['persistid']; 198 212 $info = self::getFileInfo($persistid); 213 // Only web images are reasonable for preview. We could do 214 // PDFs but in practice it's very slow, slower than you 215 // want to wait for when annotating; it's worth it later 216 // for display in the media repository 217 return $info['tmp_name'] && getimagesize($info['tmp_name']); 218 } 219 return false; 220 } 221 222 static public function alreadyPersisting($value) 223 { 224 if (isset($value['persistid'])) 225 { 226 $persistid = $value['persistid']; 227 $info = self::getFileInfo($persistid); 228 // Only web images are reasonable for preview. We could do 229 // PDFs but in practice it's very slow, slower than you 230 // want to wait for when annotating; it's worth it later 231 // for display in the media repository 199 232 return !!$info['tmp_name']; 200 233 } 201 234 return false; 202 235 } 236 203 237 204 238 static public function getFileInfo($persistid) … … 217 251 else 218 252 { 219 return false; 253 return false; 220 254 } 221 255 } … … 273 307 return 'audio/mpeg'; 274 308 } 309 310 protected function guessRTF($file) 311 { 312 $in = fopen($file, 'rb'); 313 $magic = fread($in, 5); 314 fclose($in); 315 if ($magic !== '{\\rtf') 316 { 317 return null; 318 } 319 return 'text/rtf'; 320 } 321 322 protected function guessMicrosoft($file) 323 { 324 // We look at the original name to get the rest. 325 // Sorry, but there are no reliable magic numbers 326 // that don't sometimes mislead for Microsoft Office files. 327 $in = fopen($file, "rb"); 328 $data = fread($in, 3); 329 fclose($in); 330 $maybeMicrosoft = false; 331 // Magic numbers: old Microsoft container and new zip-based Microsoft container 332 if (($data === sprintf("%c%c%c", 0xD0, 0xCF, 0x11)) || ($data === sprintf("%c%c%c", 0x50, 0x4B, 0x03))) 333 { 334 $maybeMicrosoft = true; 335 } 336 if (!$maybeMicrosoft) 337 { 338 return null; 339 } 340 $ms = array( 341 'xls' => 'application/vnd.ms-excel', 342 'ppt' => 'application/vnd.ms-powerpoint', 343 'doc' => 'application/msword', 344 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 345 'sldx' => 'application/vnd.openxmlformats-officedocument.presentationml.slide', 346 'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow', 347 'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template', 348 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 349 'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template', 350 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 351 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' 352 ); 353 if (preg_match('/\.(\w+)$/', $this->originalName, $matches)) 354 { 355 $extension = $matches[1]; 356 if (isset($ms[$extension])) 357 { 358 return $ms[$extension]; 359 } 360 } 361 return null; 362 } 363 364 protected function getMimeType($file, $fallback) 365 { 366 // The microsoft guesser needs access to the original filename. 367 // For reasons I'm not sure of, it doesn't work as a dynamic method 368 // with call_user_func. 369 $match = $this->guessMicrosoft($file); 370 if (!is_null($match)) 371 { 372 return $match; 373 } 374 375 return parent::getMimeType($file, $fallback); 376 } 275 377 } -
plugins/apostrophePlugin/trunk/lib/widget/aWidgetFormInputFilePersistent.class.php
r431 r2134 14 14 class aWidgetFormInputFilePersistent extends sfWidgetForm 15 15 { 16 16 17 /** 17 18 * @param array $options An array of options … … 51 52 public function render($name, $value = null, $attributes = array(), $errors = array()) 52 53 { 53 $exists = false; 54 if (isset($value['persistid']) && strlen($value['persistid'])) 55 { 56 $persistid = $value['persistid']; 57 $info = aValidatorFilePersistent::getFileInfo($persistid); 58 if ($info) 59 { 60 $exists = true; 61 } 62 } 63 else 64 { 65 // One implementation, not two (to inevitably drift apart) 66 $persistid = aGuid::generate(); 67 } 54 list($exists, $persistid, $extension) = $this->getExistsPersistidAndExtension($value); 68 55 $result = ''; 69 // hasOption just verifies that the option is valid, it doesn't check what,70 // if anything, was passed. Thanks to Lucjan Wilczewski71 56 $preview = $this->hasOption('image-preview') ? $this->getOption('image-preview') : false; 72 $defaultPreview = $this->hasOption('default-preview') ? $this->getOption('default-preview') : false;57 73 58 if ($exists) 74 59 { 75 $defaultPreview = false;76 }77 if ($exists || $defaultPreview)78 {79 if ($preview)80 {81 // Note change of key82 $urlStem = sfConfig::get('app_aPersistentFileUpload_preview_url', '/uploads/uploaded_image_preview');83 // This is the corresponding directory path. You have to override one84 // if you override the other. You override this one by setting85 // app_aToolkit_upload_uploaded_image_preview_dir86 $dir = aFiles::getUploadFolder("uploaded_image_preview");87 // While we're here age off stale previews88 aValidatorFilePersistent::removeOldFiles($dir);89 $imagePreview = $this->getOption('image-preview');90 if ($exists)91 {92 $source = $info['tmp_name'];93 }94 else95 {96 $source = $defaultPreview;97 }98 $info = aImageConverter::getInfo($source);99 if ($info)100 {101 $iwidth = $info['width'];102 $height = $info['height'];103 // This is safe - based on sniffed file contents and not a user supplied extension104 $format = $info['format'];105 list($iwidth, $iheight) = getimagesize($source);106 $dimensions = aDimensions::constrain($iwidth, $iheight, $format, $imagePreview);107 // A simple filename reveals less108 $imagename = "$persistid.$format";109 $url = "$urlStem/$imagename";110 $output = "$dir/$imagename";111 if ((isset($info['newfile']) && $info['newfile']) || (!file_exists($output)))112 {113 if ($imagePreview['resizeType'] === 'c')114 {115 $method = 'cropOriginal';116 }117 else118 {119 $method = 'scaleToFit';120 }121 sfContext::getInstance()->getLogger()->info("YY calling converter method $method width " . $dimensions['width'] . ' height ' . $dimensions['height']);122 aImageConverter::$method(123 $source,124 $output,125 $dimensions['width'],126 $dimensions['height']);127 sfContext::getInstance()->getLogger()->info("YY after converter");128 }129 }130 if (isset($imagePreview['markup']))131 {132 $markup = $imagePreview['markup'];133 }134 else135 {136 $markup = '<img src="%s" />';137 }138 $result .= sprintf($markup, $url);139 }140 60 $result .= $this->getOption('existing-html'); 141 61 } 62 63 if ($preview) 64 { 65 if (isset($imagePreview['markup'])) 66 { 67 $markup = $imagePreview['markup']; 68 } 69 else 70 { 71 $markup = '<img src="%s" />'; 72 } 73 $previewUrl = $this->getPreviewUrl($value, $preview); 74 if ($previewUrl !== false) 75 { 76 $result .= sprintf($markup, $previewUrl); 77 } 78 } 79 142 80 return $result . 143 81 $this->renderTag('input', … … 153 91 'value' => $persistid)); 154 92 } 155 93 94 public function getPreviewUrl($value, $imagePreview = array()) 95 { 96 list($exists, $persistid, $extension) = $this->getExistsPersistidAndExtension($value); 97 98 // hasOption just verifies that the option is valid, it doesn't check what, 99 // if anything, was passed. Thanks to Lucjan Wilczewski 100 $defaultPreview = $this->hasOption('default-preview') ? $this->getOption('default-preview') : false; 101 if ($exists) 102 { 103 $defaultPreview = false; 104 } 105 if ($exists || $defaultPreview) 106 { 107 // Note change of key 108 $urlStem = sfConfig::get('app_aPersistentFileUpload_preview_url', '/uploads/uploaded_image_preview'); 109 // This is the corresponding directory path. You have to override one 110 // if you override the other. You override this one by setting 111 // app_aToolkit_upload_uploaded_image_preview_dir 112 $dir = aFiles::getUploadFolder("uploaded_image_preview"); 113 // While we're here age off stale previews 114 aValidatorFilePersistent::removeOldFiles($dir); 115 if ($exists) 116 { 117 $info = aValidatorFilePersistent::getFileInfo($persistid); 118 $source = $info['tmp_name']; 119 } 120 else 121 { 122 $source = $defaultPreview; 123 } 124 $info = aImageConverter::getInfo($source, array('format-only' => true)); 125 $previewable = false; 126 if ($info && in_array($info['format'], array('jpg', 'png', 'gif'))) 127 { 128 $previewable = true; 129 $info = aImageConverter::getInfo($source); 130 } 131 if ($previewable) 132 { 133 $iwidth = $info['width']; 134 $iheight = $info['height']; 135 // This is safe - based on sniffed file contents and not a user supplied extension 136 $format = $info['format']; 137 $dimensions = aDimensions::constrain($iwidth, $iheight, $format, $imagePreview); 138 // A simple filename reveals less 139 $imagename = "$persistid.$format"; 140 $url = "$urlStem/$imagename"; 141 $output = "$dir/$imagename"; 142 if ((isset($info['newfile']) && $info['newfile']) || (!file_exists($output))) 143 { 144 if ($imagePreview['resizeType'] === 'c') 145 { 146 $method = 'cropOriginal'; 147 } 148 else 149 { 150 $method = 'scaleToFit'; 151 } 152 sfContext::getInstance()->getLogger()->info("YY calling converter method $method width " . $dimensions['width'] . ' height ' . $dimensions['height']); 153 aImageConverter::$method( 154 $source, 155 $output, 156 $dimensions['width'], 157 $dimensions['height']); 158 sfContext::getInstance()->getLogger()->info("YY after converter"); 159 } 160 } 161 else 162 { 163 if ($extension !== false) 164 { 165 $url = '/apostrophePlugin/images/a-icons-format-' . $extension . '.png'; 166 } 167 } 168 return $url; 169 } 170 return false; 171 } 172 173 protected function getExistsPersistidAndExtension($value) 174 { 175 // TODO: should cache this 176 $exists = false; 177 $extension = false; 178 if (isset($value['persistid']) && strlen($value['persistid'])) 179 { 180 $persistid = $value['persistid']; 181 $info = aValidatorFilePersistent::getFileInfo($persistid); 182 if ($info) 183 { 184 $exists = true; 185 if (isset($info['extension'])) 186 { 187 $extension = $info['extension']; 188 } 189 } 190 } 191 else 192 { 193 // One implementation, not two (to inevitably drift apart) 194 $persistid = aGuid::generate(); 195 } 196 197 if (!$exists) 198 { 199 $defaultPreview = $this->hasOption('default-preview') ? $this->getOption('default-preview') : false; 200 if ($defaultPreview) 201 { 202 $extension = pathinfo($defaultPreview, PATHINFO_EXTENSION); 203 } 204 } 205 206 return array($exists, $persistid, $extension); 207 } 156 208 } -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/_browser.php
r1957 r2134 44 44 <div class="a-filter-options type"> 45 45 <?php $type = isset($type) ? $type : '' ?> 46 <div class="a-filter-option"> 47 <?php echo link_to(__('Image', null, 'apostrophe'), aUrl::addParams($current, array('type' => ($type == 'image') ? '' : 'image')), array('class' => ($type=='image') ? 'selected' : '', )) ?> 48 </div> 49 <div class="a-filter-option"> 50 <?php echo link_to(__('Video', null, 'apostrophe'), aUrl::addParams($current, array('type' => ($type == 'video') ? '' : 'video')), array('class' => ($type=='video') ? 'selected' : '', )) ?> 51 </div> 52 <div class="a-filter-option"> 53 <?php echo link_to(__('PDF', null, 'apostrophe'), aUrl::addParams($current, array('type' => ($type == 'pdf') ? '' : 'pdf')), array('class' => ($type=='pdf') ? 'selected' : '', )) ?> 54 </div> 46 <?php $typesInfo = aMediaTools::getOption('types') ?> 47 <?php foreach ($typesInfo as $typeName => $typeInfo): ?> 48 <div class="a-filter-option"> 49 <?php echo link_to(a_($typeInfo['label']), aUrl::addParams($current, array('type' => ($typeName == $type) ? '' : $typeName)), array('class' => ($typeName == $type) ? 'selected' : '', )) ?> 50 </div> 51 <?php endforeach ?> 55 52 </div> 56 53 </div> -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/_edit.php
r2058 r2134 8 8 $n = isset($n) ? $sf_data->getRaw('n') : null; 9 9 ?> 10 <?php use_helper(' I18N') ?>10 <?php use_helper('a') ?> 11 11 12 12 <?php if (!isset($n)): ?> <?php $n = 0 ?> <?php endif ?> 13 13 14 <?php // if there is an $item then we're editing one exiting media item, if not ?> 15 <?php // we're part of an annotation of potentially several new items in a bigger form ?> 16 14 17 <?php if (!$item): ?> 15 <li class="a-media-item <?php echo ($n%2) ? "odd" : "even" ?>" >18 <li class="a-media-item <?php echo ($n%2) ? "odd" : "even" ?>" id="a-media-item-<?php echo $i ?>"> 16 19 <div class="a-media-item-edit-form"> 17 20 <?php endif ?> … … 19 22 <?php if ($item): ?> 20 23 <form method="POST" id="a-media-edit-form" enctype="multipart/form-data" 21 action="<?php echo url_for(aUrl::addParams("aMedia/edit Image",24 action="<?php echo url_for(aUrl::addParams("aMedia/edit", 22 25 array("slug" => $item->getSlug())))?>"> 23 26 <?php endif ?> 24 25 <?php $previewAvailable = aValidatorFilePersistent::previewAvailable($form['file']->getValue()) ?> 26 <?php if ($previewAvailable || $item): ?> 27 28 <div class="a-form-row image"> 29 <?php if (0): ?> 30 <?php // Maybe Rick doesn't want this... ?> 31 <?php echo $form['file']->renderLabel() ?> 32 <?php endif ?> 33 <?php // But we must have this ?> 34 <?php echo $form['file']->renderError() ?> 35 <?php echo $form['file']->render() ?> 36 <?php else: ?> 37 <div class="a-form-row newfile"> 38 <?php echo $form['file']->renderRow() ?> 39 </div> 40 <?php endif ?> 41 </div> 27 28 <?php // This is how we get the preview (which might be a rendering or a large icon, depending on the type) ?> 29 <?php // outside of the widget. Jamming it into the widget made templating weird ?> 30 <div class="a-form-row preview"> 31 <?php echo image_tag($form['file']->getWidget()->getPreviewUrl($form['file']->getValue(), aMediaTools::getOption('gallery_constraints'))) ?> 32 <?php if (!$item): ?> 33 <a class="a-media-remove-file" href="#">x</a> 34 <?php a_js_call('apostrophe.mediaEnableRemoveButton(?)', $i) ?> 35 <?php endif ?> 36 </div> 37 38 <?php // The label says 'Replace File' now, see BaseaMediaEditForm ?> 39 <div class="a-form-row file"> 40 <?php echo $form['file']->renderLabel() ?> 41 <?php echo $form['file']->renderError() ?> 42 <?php echo $form['file']->render() ?> 43 </div> 42 44 43 45 <div class="a-form-row title"> … … 49 51 </div> 50 52 51 <?php echo $form['id']->render() ?>52 53 <div class="a-form-row description"> 53 54 <?php echo $form['description']->renderLabel() ?> -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/_editLinks.php
r1957 r2134 7 7 <ul class="a-ui a-controls"> 8 8 9 <?php if ($mediaItem->getType() === 'video'): ?> 10 <li><?php echo link_to(__("Edit", null, 'apostrophe'), "aMedia/editVideo", array("query_string" => http_build_query(array("slug" => $mediaItem->getSlug())), "class" => "a-btn icon a-edit")) ?></li> 11 <?php elseif ($mediaItem->getType() === 'pdf'): ?> 12 <li><?php echo link_to(__("Edit", null, 'apostrophe'), "aMedia/editPdf", array("query_string" => http_build_query(array("slug" => $mediaItem->getSlug())), "class" => "a-btn icon a-edit")) ?></li> 13 <?php else: ?> 14 <li><?php echo link_to(__("Edit", null, 'apostrophe'), "aMedia/editImage", array("query_string" => http_build_query(array("slug" => $mediaItem->getSlug())), "class" => "a-btn icon a-edit")) ?></li> 15 <?php endif ?> 16 17 <?php if ($mediaItem->getType() !== 'video' && $sf_params->get('action') == 'show'): ?> 9 <li><?php echo link_to(a_("Edit"), "aMedia/edit", array("query_string" => http_build_query(array("slug" => $mediaItem->getSlug())), "class" => "a-btn icon a-edit")) ?></li> 10 11 <?php if ($mediaItem->getDownloadable() && $sf_params->get('action') == 'show'): ?> 18 12 <li class="a-media-download-original"> 19 13 <?php // download link ?> -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/_mediaItem.php
r1917 r2134 44 44 </li> 45 45 46 <?php // Stored as HTML ?>47 46 <li class="a-media-item-title"> 48 47 <h3> … … 52 51 </li> 53 52 53 <?php // John: you could use $mediaItem->format to choose an icon here. Make sure ?> 54 <?php // you have a default icon if it's not on your list of awesome icons ?> 54 55 <li class="a-media-item-description"><?php echo $mediaItem->getDescription() ?></li> 55 56 <?php if ($mediaItem->getWidth()): ?> … … 61 62 <li class="a-media-item-tags a-media-item-meta"><?php echo __('<span>Tags:</span> %tags%', array('%tags%' => get_partial('aMedia/showTags', array('tags' => $mediaItem->getTags()))), 'apostrophe') ?></li> 62 63 63 <?php if ($mediaItem->get Type() === 'pdf'): ?>64 <?php if ($mediaItem->getDownloadable()): ?> 64 65 <li class="a-media-item-link a-media-item-meta"> 65 66 <?php echo __('<span>URL:</span> %urlfield%', array('%urlfield%' => -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/editMultipleSuccess.php
r2058 r2134 5 5 $form = isset($form) ? $sf_data->getRaw('form') : null; 6 6 ?> 7 <?php use_helper(' I18N', 'jQuery', 'a') ?>7 <?php use_helper('a') ?> 8 8 <?php slot('body_class') ?>a-media<?php end_slot() ?> 9 9 … … 13 13 14 14 <div class="a-media-toolbar"> 15 <h3><?php echo __('Annotate Images', null, 'apostrophe') ?></h3>15 <h3><?php echo __('Annotate ' . aMediaTools::getBestTypeLabel(), null, 'apostrophe') ?></h3> 16 16 </div> 17 17 18 18 <div class="a-media-library"> 19 <form method="POST" action="<?php echo url_for("aMedia/edit Images") ?>" enctype="multipart/form-data" id="a-media-edit-form">19 <form method="POST" action="<?php echo url_for("aMedia/editMultiple") ?>" enctype="multipart/form-data" id="a-media-edit-form"> 20 20 <?php echo $form->renderHiddenFields() ?> 21 21 22 <input type="hidden" name="active" value="<?php echo implode(",", $active) ?>" />23 24 22 <?php $n = 0 ?> 25 23 … … 30 28 <?php // (they get nested when embedded forms are present), but ?> 31 29 <?php // it supports the same methods as a form for rendering purposes ?> 32 <?php include_partial('aMedia/editImage', 33 array( 34 "item" => false, 35 "firstPass" => $firstPass, 36 "form" => $form["item-$i"], 37 "n" => $n, 38 'i' => $i, 39 'itemFormScripts' => 'false', 40 )) ?> 30 31 <?php // Please do not remove this div, I need it to implement the remove button ?> 32 <div id="a-media-editor-<?php echo $i ?>"> 33 <?php include_partial('aMedia/edit', 34 array( 35 "item" => false, 36 "firstPass" => $firstPass, 37 "form" => $form["item-$i"], 38 "n" => $n, 39 'i' => $i, 40 'itemFormScripts' => 'false', 41 )) ?> 42 </div> 41 43 <?php $n++ ?> 42 44 <?php endif ?> … … 48 50 <?php //We should wrap this with logic to say 'photo' if only one object has been uploaded ?> 49 51 <ul class="a-ui a-controls"> 50 <li><input type="submit" name="submit" value="<?php echo __('Save Images', null, 'apostrophe') ?>" class="a-btn a-submit" /></li> 51 <li><?php echo link_to(__("Cancel", null, 'apostrophe'), "aMedia/resume", array("class"=>"a-btn icon a-cancel")) ?></li> 52 <li><input type="submit" name="submit" value="<?php echo a_('Save ' . aMediaTools::getBestTypeLabel()) ?>" class="a-btn a-submit" /></li> 53 <?php // I use a-cancel and a-media-edit-multiple to find and trigger this cancel button in JS ?> 54 <li><?php echo link_to(a_("Cancel"), "aMedia/resume", array("class"=>"a-btn icon a-media-edit-multiple-cancel")) ?></li> 52 55 </ul> 53 56 </form> -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/editSuccess.php
r1957 r2134 17 17 18 18 <div class="a-media-library"> 19 <?php include_partial('aMedia/edit Image', array('item' => $item, 'firstPass' => false, 'form' => $form)) ?>19 <?php include_partial('aMedia/edit', array('item' => $item, 'form' => $form)) ?> 20 20 </div> 21 22 21 </div> -
plugins/apostrophePlugin/trunk/modules/aMedia/templates/indexSuccess.php
r1957 r2134 38 38 39 39 <?php if (aMediaTools::userHasUploadPrivilege()): ?> 40 <ul class="a-ui a-controls">40 <ul class="a-ui a-controls"> 41 41 42 <?php if (!($selecting && $type && ($type !== 'image'))): ?> 43 <li><a href="<?php echo url_for("aMedia/uploadImages") ?>" class="a-btn icon big a-add"><?php echo __('Add Images', null, 'apostrophe') ?></a></li> 44 <?php endif ?> 45 46 <?php if (!($selecting && $type && ($type !== 'video'))): ?> 47 <li><a href="<?php echo url_for("aMedia/newVideo") ?>" class="a-btn icon big a-add"><?php echo __('Add Video', null, 'apostrophe') ?></a></li> 48 <?php endif ?> 49 50 <?php if (!($selecting && $type && ($type !== 'pdf'))): ?> 51 <li><a href="<?php echo url_for("aMedia/editPdf") ?>" class="a-btn icon big a-add"><?php echo __('Add PDF', null, 'apostrophe') ?></a></li> 52 <?php endif ?> 42 <?php $typeLabel = aMediaTools::getBestTypeLabel() ?> 43 <?php if ($uploadAllowed): ?> 44 <li><a href="<?php echo url_for("aMedia/upload") ?>" class="a-btn icon big a-add"><?php echo a_('Upload ' . $typeLabel) ?></a></li> 45 <?php endif ?> 46 <?php if ($embedAllowed): ?> 47 <li><a href="<?php echo url_for("aMedia/embed") ?>" class="a-btn icon big a-add"><?php echo a_('Embed ' . $typeLabel) ?></a></li> 48 <?php endif ?> 53 49 </ul> 54 50 <?php endif ?> -
plugins/apostrophePlugin/trunk/web/css/a.css
- Property svn:mergeinfo changed (with no actual effect on merging)
-
plugins/apostrophePlugin/trunk/web/images
- Property svn:mergeinfo changed (with no actual effect on merging)
-
plugins/apostrophePlugin/trunk/web/js/a.js
r2124 r2134 367 367 } 368 368 369 this.mediaEnableRemoveButton = function(i) 370 { 371 var editor = $('#a-media-item-' + i); 372 editor.find('.a-media-remove-file').click(function() 373 { 374 editor.remove(); 375 if ($('.a-media-item').length == 0) 376 { 377 // This is a bit hacky 378 document.location = $('.a-media-edit-multiple-cancel').attr('href'); 379 } 380 return false; 381 }); 382 } 383 369 384 // console.log wrapper prevents JS errors if we leave an apostrophe.log call hanging out in our code someplace 370 385 this.log = function(output)

