Index: trunk/phase3/includes/filerepo/file/File.php |
— | — | @@ -742,89 +742,6 @@ |
743 | 743 | } |
744 | 744 | |
745 | 745 | /** |
746 | | - * Do the work of a transform (from an original into a thumb). |
747 | | - * Contains filesystem-specific functions. |
748 | | - * |
749 | | - * @param $thumbName string: the name of the thumbnail file. |
750 | | - * @param $thumbUrl string: the URL of the thumbnail file. |
751 | | - * @param $params Array: an associative array of handler-specific parameters. |
752 | | - * Typical keys are width, height and page. |
753 | | - * @param $flags Integer: a bitfield, may contain self::RENDER_NOW to force rendering |
754 | | - * |
755 | | - * @return MediaTransformOutput|null |
756 | | - */ |
757 | | - protected function maybeDoTransform( $thumbName, $thumbUrl, $params, $flags = 0 ) { |
758 | | - global $wgIgnoreImageErrors, $wgThumbnailEpoch; |
759 | | - |
760 | | - $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path |
761 | | - if ( $this->repo ) { |
762 | | - // Defer rendering if a 404 handler is set up... |
763 | | - if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) { |
764 | | - wfDebug( __METHOD__ . " transformation deferred." ); |
765 | | - // XXX: Pass in the storage path even though we are not rendering anything |
766 | | - // and the path is supposed to be an FS path. This is due to getScalerType() |
767 | | - // getting called on the path and clobbering $thumb->getUrl() if it's false. |
768 | | - return $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); |
769 | | - } |
770 | | - // Clean up broken thumbnails as needed |
771 | | - $this->migrateThumbFile( $thumbName ); |
772 | | - // Check if an up-to-date thumbnail already exists... |
773 | | - wfDebug( __METHOD__.": Doing stat for $thumbPath\n" ); |
774 | | - if ( $this->repo->fileExists( $thumbPath ) && !( $flags & self::RENDER_FORCE ) ) { |
775 | | - $timestamp = $this->repo->getFileTimestamp( $thumbPath ); |
776 | | - if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) { |
777 | | - // XXX: Pass in the storage path even though we are not rendering anything |
778 | | - // and the path is supposed to be an FS path. This is due to getScalerType() |
779 | | - // getting called on the path and clobbering $thumb->getUrl() if it's false. |
780 | | - $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); |
781 | | - $thumb->setStoragePath( $thumbPath ); |
782 | | - return $thumb; |
783 | | - } |
784 | | - } elseif ( $flags & self::RENDER_FORCE ) { |
785 | | - wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" ); |
786 | | - } |
787 | | - } |
788 | | - |
789 | | - // Create a temp FS file with the same extension and the thumbnail |
790 | | - $thumbExt = FileBackend::extensionFromPath( $thumbPath ); |
791 | | - $tmpFile = TempFSFile::factory( 'transform_', $thumbExt ); |
792 | | - if ( !$tmpFile ) { |
793 | | - return $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); |
794 | | - } |
795 | | - $tmpThumbPath = $tmpFile->getPath(); // path of 0-byte temp file |
796 | | - |
797 | | - // Actually render the thumbnail... |
798 | | - $thumb = $this->handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params ); |
799 | | - $tmpFile->bind( $thumb ); // keep alive with $thumb |
800 | | - |
801 | | - if ( !$thumb ) { // bad params? |
802 | | - $thumb = null; |
803 | | - } elseif ( $thumb->isError() ) { // transform error |
804 | | - $this->lastError = $thumb->toText(); |
805 | | - // Ignore errors if requested |
806 | | - if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) { |
807 | | - $thumb = $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params ); |
808 | | - } |
809 | | - } elseif ( $thumb->hasFile() && !$thumb->fileIsSource() ) { |
810 | | - $backend = $this->repo->getBackend(); |
811 | | - // Copy the thumbnail from the file system into storage. This avoids using |
812 | | - // FileRepo::store(); getThumbPath() uses a different zone in some subclasses. |
813 | | - $backend->prepare( array( 'dir' => dirname( $thumbPath ) ) ); |
814 | | - $status = $backend->store( |
815 | | - array( 'src' => $tmpThumbPath, 'dst' => $thumbPath, 'overwrite' => 1 ), |
816 | | - array( 'force' => 1, 'nonLocking' => 1, 'allowStale' => 1 ) |
817 | | - ); |
818 | | - if ( $status->isOK() ) { |
819 | | - $thumb->setStoragePath( $thumbPath ); |
820 | | - } else { |
821 | | - $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); |
822 | | - } |
823 | | - } |
824 | | - |
825 | | - return $thumb; |
826 | | - } |
827 | | - |
828 | | - /** |
829 | 746 | * Return either a MediaTransformError or placeholder thumbnail (if $wgIgnoreImageErrors) |
830 | 747 | * |
831 | 748 | * @param $thumbPath string Thumbnail storage path |
— | — | @@ -850,41 +767,106 @@ |
851 | 768 | * @param $params Array: an associative array of handler-specific parameters. |
852 | 769 | * Typical keys are width, height and page. |
853 | 770 | * @param $flags Integer: a bitfield, may contain self::RENDER_NOW to force rendering |
854 | | - * @return MediaTransformOutput | false |
| 771 | + * @return MediaTransformOutput|false |
855 | 772 | */ |
856 | 773 | function transform( $params, $flags = 0 ) { |
857 | | - global $wgUseSquid; |
| 774 | + global $wgUseSquid, $wgIgnoreImageErrors, $wgThumbnailEpoch; |
858 | 775 | |
859 | 776 | wfProfileIn( __METHOD__ ); |
860 | 777 | do { |
861 | 778 | if ( !$this->canRender() ) { |
862 | | - // not a bitmap or renderable image, don't try. |
863 | 779 | $thumb = $this->iconThumb(); |
864 | | - break; |
| 780 | + break; // not a bitmap or renderable image, don't try |
865 | 781 | } |
866 | 782 | |
867 | 783 | // Get the descriptionUrl to embed it as comment into the thumbnail. Bug 19791. |
868 | | - $descriptionUrl = $this->getDescriptionUrl(); |
| 784 | + $descriptionUrl = $this->getDescriptionUrl(); |
869 | 785 | if ( $descriptionUrl ) { |
870 | 786 | $params['descriptionUrl'] = wfExpandUrl( $descriptionUrl, PROTO_CANONICAL ); |
871 | 787 | } |
872 | 788 | |
873 | 789 | $script = $this->getTransformScript(); |
874 | | - if ( $script && !($flags & self::RENDER_NOW) ) { |
| 790 | + if ( $script && !( $flags & self::RENDER_NOW ) ) { |
875 | 791 | // Use a script to transform on client request, if possible |
876 | 792 | $thumb = $this->handler->getScriptedTransform( $this, $script, $params ); |
877 | | - if( $thumb ) { |
| 793 | + if ( $thumb ) { |
878 | 794 | break; |
879 | 795 | } |
880 | 796 | } |
881 | 797 | |
882 | 798 | $normalisedParams = $params; |
883 | 799 | $this->handler->normaliseParams( $this, $normalisedParams ); |
| 800 | + |
884 | 801 | $thumbName = $this->thumbName( $normalisedParams ); |
885 | 802 | $thumbUrl = $this->getThumbUrl( $thumbName ); |
| 803 | + $thumbPath = $this->getThumbPath( $thumbName ); // final thumb path |
886 | 804 | |
887 | | - $thumb = $this->maybeDoTransform( $thumbName, $thumbUrl, $params, $flags ); |
| 805 | + if ( $this->repo ) { |
| 806 | + // Defer rendering if a 404 handler is set up... |
| 807 | + if ( $this->repo->canTransformVia404() && !( $flags & self::RENDER_NOW ) ) { |
| 808 | + wfDebug( __METHOD__ . " transformation deferred." ); |
| 809 | + // XXX: Pass in the storage path even though we are not rendering anything |
| 810 | + // and the path is supposed to be an FS path. This is due to getScalerType() |
| 811 | + // getting called on the path and clobbering $thumb->getUrl() if it's false. |
| 812 | + $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); |
| 813 | + break; |
| 814 | + } |
| 815 | + // Clean up broken thumbnails as needed |
| 816 | + $this->migrateThumbFile( $thumbName ); |
| 817 | + // Check if an up-to-date thumbnail already exists... |
| 818 | + wfDebug( __METHOD__.": Doing stat for $thumbPath\n" ); |
| 819 | + if ( $this->repo->fileExists( $thumbPath ) && !( $flags & self::RENDER_FORCE ) ) { |
| 820 | + $timestamp = $this->repo->getFileTimestamp( $thumbPath ); |
| 821 | + if ( $timestamp !== false && $timestamp >= $wgThumbnailEpoch ) { |
| 822 | + // XXX: Pass in the storage path even though we are not rendering anything |
| 823 | + // and the path is supposed to be an FS path. This is due to getScalerType() |
| 824 | + // getting called on the path and clobbering $thumb->getUrl() if it's false. |
| 825 | + $thumb = $this->handler->getTransform( $this, $thumbPath, $thumbUrl, $params ); |
| 826 | + $thumb->setStoragePath( $thumbPath ); |
| 827 | + break; |
| 828 | + } |
| 829 | + } elseif ( $flags & self::RENDER_FORCE ) { |
| 830 | + wfDebug( __METHOD__ . " forcing rendering per flag File::RENDER_FORCE\n" ); |
| 831 | + } |
| 832 | + } |
888 | 833 | |
| 834 | + // Create a temp FS file with the same extension and the thumbnail |
| 835 | + $thumbExt = FileBackend::extensionFromPath( $thumbPath ); |
| 836 | + $tmpFile = TempFSFile::factory( 'transform_', $thumbExt ); |
| 837 | + if ( !$tmpFile ) { |
| 838 | + $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); |
| 839 | + break; |
| 840 | + } |
| 841 | + $tmpThumbPath = $tmpFile->getPath(); // path of 0-byte temp file |
| 842 | + |
| 843 | + // Actually render the thumbnail... |
| 844 | + $thumb = $this->handler->doTransform( $this, $tmpThumbPath, $thumbUrl, $params ); |
| 845 | + $tmpFile->bind( $thumb ); // keep alive with $thumb |
| 846 | + |
| 847 | + if ( !$thumb ) { // bad params? |
| 848 | + $thumb = null; |
| 849 | + } elseif ( $thumb->isError() ) { // transform error |
| 850 | + $this->lastError = $thumb->toText(); |
| 851 | + // Ignore errors if requested |
| 852 | + if ( $wgIgnoreImageErrors && !( $flags & self::RENDER_NOW ) ) { |
| 853 | + $thumb = $this->handler->getTransform( $this, $tmpThumbPath, $thumbUrl, $params ); |
| 854 | + } |
| 855 | + } elseif ( $this->repo && $thumb->hasFile() && !$thumb->fileIsSource() ) { |
| 856 | + $backend = $this->repo->getBackend(); |
| 857 | + // Copy the thumbnail from the file system into storage. This avoids using |
| 858 | + // FileRepo::store(); getThumbPath() uses a different zone in some subclasses. |
| 859 | + $backend->prepare( array( 'dir' => dirname( $thumbPath ) ) ); |
| 860 | + $status = $backend->store( |
| 861 | + array( 'src' => $tmpThumbPath, 'dst' => $thumbPath, 'overwrite' => 1 ), |
| 862 | + array( 'force' => 1, 'nonLocking' => 1, 'allowStale' => 1 ) |
| 863 | + ); |
| 864 | + if ( $status->isOK() ) { |
| 865 | + $thumb->setStoragePath( $thumbPath ); |
| 866 | + } else { |
| 867 | + $thumb = $this->transformErrorOutput( $thumbPath, $thumbUrl, $params, $flags ); |
| 868 | + } |
| 869 | + } |
| 870 | + |
889 | 871 | // Purge. Useful in the event of Core -> Squid connection failure or squid |
890 | 872 | // purge collisions from elsewhere during failure. Don't keep triggering for |
891 | 873 | // "thumbs" which have the main image URL though (bug 13776) |
— | — | @@ -893,7 +875,7 @@ |
894 | 876 | SquidUpdate::purge( array( $thumbUrl ) ); |
895 | 877 | } |
896 | 878 | } |
897 | | - } while (false); |
| 879 | + } while ( false ); |
898 | 880 | |
899 | 881 | wfProfileOut( __METHOD__ ); |
900 | 882 | return is_object( $thumb ) ? $thumb : false; |