+
+ = t("Image optimizer settings") ?>
+
+
+ = t("This module uses three underlying toolkits, all performing lossless transformations.")." ".
+ t("You can set the paths to each of the three toolkits below.")." ".
+ t("By default, this module uses it's own pre-compiled versions, included as libraries.")." ".
+ t("Additionally, your server may have copies installed elsewhere (see table below).") ?>
+
+
+ |
+ = t("Name and author") ?> |
+ = t("Server-installed path") ?> |
+ = t("Configuration status") ?> |
+
+
+ JPG |
+ Jpegtran = t("by") ?> Jpegclub |
+ = $installed_path_jpg ?> |
+ = $version_jpg ?> |
+
+
+ PNG |
+ OptiPNG = t("by") ?> Cosmin Truta et al. |
+ = $installed_path_png ?> |
+ = $version_png ?> |
+
+
+ GIF |
+ GIFsicle = t("by") ?> LCDF |
+ = $installed_path_gif ?> |
+ = $version_gif ?> |
+
+
+ = t("This module was inspired by the WordPress module")."
EWWW Image Optimizer ".t("and the Gallery3 module")."
Jpegtran." ?>
+
+
+ = t("Notes:") ?>
+ 1. = t("Remove all meta data") ?>: = t("recommended for thumb images - 80% size reduction typical, which drastically changes page load speed") ?>
+ 2. = t("Make images progressive/interlaced") ?>: = t("recommended for resize images - provides preview of photo during download") ?>
+ 3. = t("Conversion") ?>: = t("recommended for thumb images - converting PNG/GIF to JPG can reduce the size by a huge amount, again helping page load speed") ?>
+ 4. = t("Update mode") ?>: = t("used to speed up initial rebuild to optimize existing images by deactivating all other graphics rules - MUST ensure that no new images are created while this is enabled (use maintenance mode if needed), and MUST disable once initial rebuild is done.") ?>
+ 5. = t("Windows / Linux") ?>: = t("the module's lib directory includes both Windows and Linux versions of the toolkits. For security reasons, Windows should not be used on production sites. Both versions are provided here to enable development copies to still run Windows without issue.") ?>
+
+ = $form ?>
+
\ No newline at end of file
diff --git a/3.0/modules/proofsheet/controllers/proofsheet.php b/3.0/modules/proofsheet/controllers/proofsheet.php
index 3dd91b87..c3713e42 100644
--- a/3.0/modules/proofsheet/controllers/proofsheet.php
+++ b/3.0/modules/proofsheet/controllers/proofsheet.php
@@ -1,441 +1,446 @@
-is_album()) {
- throw new Kohana_Exception('container is not an album: '.$container->relative_path());
- }
-
- $pdfname = (empty($container->name))
- ? 'Gallery.pdf' // @todo purified_version_of($container->title).'.pdf'
- : $container->name.'.pdf';
- $headerText = $container->title;
- $headerLink = $container->abs_url();
- break;
-
- case "tag":
- // @todo: if the module is not installed, it crash
- $container = ORM::factory("tag", $id);
- if (is_null($container->name)) {
- throw new Kohana_Exception('container is not a tag: '.$id);
- }
-
- $pdfname = $container->name.'.pdf';
- $headerText = $container->name;
- $headerLink = $container->abs_url();
- break;
-
- default:
- throw new Kohana_Exception('unhandled container type: '.$container_type);
- }
- $files = $this->getFilesList($container);
-
- /**
- * Configure PDF file. These are all of the parameters that are used to
- * format the proof sheet. If you'd like to tweak the formatting, here's
- * where to do it.
- */
- switch($page_type) {
- case "ltr":
- // Setup for LTR 8.5" x 11" paper (215.9mm x 279.4mm)
- $cfg = array(
- 'pageW' => 215.9, // mm
- 'pageH' => 279.4, // mm
- 'imageNumW' => 5, // integer number
- 'imageNumH' => 5, // integer number
- 'imageSizeW' => 36, // mm
- 'imageSizeH' => 36, // mm
- 'marginL' => 10, // mm
- 'marginR' => 10, // mm
- 'marginT' => 21, // mm (header goes in here)
- 'marginB' => 20, // mm (footer goes in here)
- 'headerSpace' => 2, // mm (header to top row of images and to link icon)
- 'footerSpace' => 2, // mm (bottom row of captions to footer)
- 'captionSpace' => 1, // mm (bottom of image to caption)
- 'headerFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 14, // pt
- 'style' => 'B', // combo of B, I, U
- 'posn' => 'L', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 0),// Blue 0-255
- 'footerFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 12, // pt
- 'style' => 'B', // combo of B, I, U
- 'posn' => 'R', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 0),// Blue 0-255
- 'captionFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 8, // pt
- 'style' => 'U', // combo of B, I, U
- 'posn' => 'C', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 255),// Blue 0-255
- );
- break;
- case "a4":
- // Setup for A4 210mm x 297mm paper (8.27" x 11.69")
- $cfg = array(
- 'pageW' => 210, // mm
- 'pageH' => 297, // mm
- 'imageNumW' => 5, // integer number
- 'imageNumH' => 6, // integer number
- 'imageSizeW' => 36, // mm
- 'imageSizeH' => 36, // mm
- 'marginL' => 8, // mm
- 'marginR' => 8, // mm
- 'marginT' => 19, // mm (header goes in here)
- 'marginB' => 18, // mm (footer goes in here)
- 'headerSpace' => 2, // mm (header to top row of images and to link icon)
- 'footerSpace' => 2, // mm (bottom row of captions to footer)
- 'captionSpace' => 1, // mm (bottom of image to caption)
- 'headerFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 14, // pt
- 'style' => 'B', // combo of B, I, U
- 'posn' => 'L', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 0),// Blue 0-255
- 'footerFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 12, // pt
- 'style' => 'B', // combo of B, I, U
- 'posn' => 'R', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 0),// Blue 0-255
- 'captionFont' => array(
- 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
- 'size' => 8, // pt
- 'style' => 'U', // combo of B, I, U
- 'posn' => 'C', // combo of L, C, R
- 'r' => 0, // Red 0-255
- 'g' => 0, // Green 0-255
- 'b' => 255),// Blue 0-255
- );
- break;
- default:
- throw new Kohana_Exception('unhandled page type: '.$page_type);
- }
-
- // Here are some other parameters that need defining
- $cfg['footerTextPage'] = 'Page '; // Note that this text isn't autofixed by translate module
- $cfg['footerTextSlash'] = ' / ';
- $cfg['headerLinkIconPath'] = MODPATH . 'proofsheet/images/ico-link.png';
- $cfgImageMissing['iconPath'] = MODPATH . 'proofsheet/images/image_missing.png';
- $cfgImageMissing['iconType'] = 'PNG'; // PNG or JPG is most robust, GIF okay only if GD is installed
- $pt2mm = 25.4/72; // 25.4mm=1in=72pt
-
- // Derive a bunch more parameters. These are all dependent on the above stuff.
- $cfg['headerH'] = $pt2mm * $cfg['headerFont']['size'];
- $cfg['footerH'] = $pt2mm * $cfg['footerFont']['size'];
- $cfg['captionH'] = $pt2mm * $cfg['captionFont']['size'];
- $cfg['imageSpaceW'] = ($cfg['pageW']-$cfg['marginL']-$cfg['marginR']-$cfg['imageNumW']*$cfg['imageSizeW']) / ($cfg['imageNumW']-1);
- $cfg['imageSpaceH'] = ($cfg['pageH']-$cfg['marginT']-$cfg['marginB']-$cfg['imageNumH']*$cfg['imageSizeH']-$cfg['captionH']-$cfg['captionSpace']) / ($cfg['imageNumH']-1);
- $linkInfo = getimagesize($cfg['headerLinkIconPath']);
- $cfg['headerLinkH'] = $cfg['headerH']; // I'm defining this to be the same as the text, but you can change it here.
- $cfg['headerLinkW'] = $linkInfo[0] / $linkInfo[1] * $cfg['headerLinkH'];
- $cfg['headerW'] = $cfg['pageW']-$cfg['marginL']-$cfg['marginR']-$cfg['headerLinkW']-$cfg['headerSpace'];
- $cfg['footerW'] = $cfg['pageW']-$cfg['marginL']-$cfg['marginR'];
- $cfg['captionW'] = $cfg['imageSizeW']; // I'm defining this to be the same as the image, but you can change it here.
- $cfg['headerX'] = $cfg['marginL'];
- $cfg['headerLinkX'] = $cfg['marginL']+$cfg['headerW'];
- $cfg['footerX'] = $cfg['marginL'];
- $cfg['headerY'] = $cfg['marginT']-$cfg['headerH']-$cfg['headerSpace'];
- $cfg['headerLinkY'] = $cfg['marginT']-$cfg['headerLinkH']-$cfg['headerSpace'];
- $cfg['footerY'] = $cfg['pageH']-$cfg['marginB']+$cfg['footerSpace'];
- $cfg['imageNum'] = $cfg['imageNumW']*$cfg['imageNumH'];
- $cfgImageMissing['iconInfo'] = getimagesize($cfgImageMissing['iconPath']);
- $cfgImageMissing['GDflag'] = graphics::detect_toolkits()->gd>installed; // FPDF uses GD to convert GIFs
-
- /**
- * Initialize and build PDF... the main routine. Note that almost all of the
- * useful configuration parameters are already defined above.
- */
-
- // Initialize PDF, disable automatic margins and page breaks
- $pdf = new proofsheet_PDF('P', 'mm', array($cfg['pageW'],$cfg['pageH']) );
- $pdf->SetMargins(0,0);
- $pdf->SetAutoPageBreak(0);
-
- // Build the PDF
- $numpages = floor(count($files)/$cfg['imageNum'])+1;
- $i = 0;
- foreach($files as $f_path => $f_info) {
- // Initialize new pages, add header and footer
- if (($i % $cfg['imageNum'])==0) {
- $pdf->AddPage();
- $pdf->printText($headerText, $cfg['headerFont'], $cfg['headerX'], $cfg['headerY'], $cfg['headerW'], $cfg['headerH']);
- $pdf->printImage($cfg['headerLinkIconPath'], $cfg['headerLinkX'], $cfg['headerLinkY'], $cfg['headerLinkW'], $cfg['headerLinkH'], $headerLink, $cfgImageMissing);
- $footerText = $cfg['footerTextPage'] . strval(floor($i/$cfg['imageNum'])+1) . $cfg['footerTextSlash'] . strval($numpages);
- $pdf->printText($footerText, $cfg['footerFont'], $cfg['footerX'], $cfg['footerY'], $cfg['footerW'], $cfg['footerH']);
- }
- // Add thumbnail and caption
- $x = $cfg['marginL'] + ($cfg['imageSizeW']+$cfg['imageSpaceW']) * ( $i % $cfg['imageNumW']);
- $y = $cfg['marginT'] + ($cfg['imageSizeH']+$cfg['imageSpaceH']) * (floor($i/$cfg['imageNumW']) % $cfg['imageNumH']);
- $pdf->printImage($f_path, $x, $y, $cfg['imageSizeW'], $cfg['imageSizeH'], null, $cfgImageMissing);
- $pdf->printText($f_info['name'], $cfg['captionFont'], $x, $y+$cfg['imageSizeH']+$cfg['captionSpace'], $cfg['captionW'], $cfg['captionH'], $f_info['url']);
- // Increment index and loop
- $i++;
- }
-
- /**
- * Output the PDF file. I wrote it in two versions (one should always be commented out).
- */
- // Using a method similar to downloadalbum
- $pdfstring = $pdf->Output('','S');
- $this->prepareOutput();
- $this->sendHeaders($pdfname, strlen($pdfstring));
- echo $pdfstring;
-
- // Using FPDF directly
- //$pdf->Output($pdfname,'I');
-
- }
-
- /**
- * Return the files that must be included in the archive.
- * This is largely borrowed from downloadalbum, but does have
- * significant modifications.
- */
- private function getFilesList($container) {
- $files = array();
-
- if( $container instanceof Item_Model && $container->is_album() ) {
- $items = $container->viewable()
- ->descendants(null, null, array(array("type", "<>", "album")));
-
- foreach($items as $i) {
- if (!access::can('view_full', $i)) {
- continue;
- }
-
- $thumb_realpath = realpath($i->thumb_path());
- if (!is_readable($thumb_realpath)) {
- continue;
- }
-
- $files[$thumb_realpath] = array('url' => $i->abs_url(), 'name' => $i->title);
- }
-
- } else if( $container instanceof Tag_Model ) {
- $items = $container->items();
- foreach($items as $i) {
- if (!access::can('view_full', $i)) {
- continue;
- }
-
- if( $i->is_album() ) {
- foreach($this->getFilesList($i) as $f_name => $f_info) {
- $files[$f_name] = $f_info;
- }
-
- } else {
- $thumb_realpath = realpath($i->thumb_path());
- if (!is_readable($thumb_realpath)) {
- continue;
- }
-
- $files[$thumb_realpath] = array('url' => $i->abs_url(), 'name' => $i->title);
-
- }
- }
- }
-
- if (count($files) === 0) {
- throw new Kohana_Exception('no thumb files in ['.$container->name.']');
- }
-
- return $files;
- }
-
-
- /**
- * See system/helpers/download.php
- * This is borrowed from downloadalbum without changes.
- */
- private function prepareOutput() {
- // Close output buffers
- Kohana::close_buffers(FALSE);
- // Clear any output
- Event::add('system.display', create_function('', 'Kohana::$output = "";'));
- }
-
- /**
- * See system/helpers/download.php
- * This is borrowed from downloadalbum without changes.
- */
- private function sendHeaders($filename, $filesize = null) {
- if (!is_null($filesize)) {
- header('Content-Length: '.$filesize);
- }
-
- // Retrieve MIME type by extension
- $mime = Kohana::config('mimes.'.strtolower(substr(strrchr($filename, '.'), 1)));
- $mime = empty($mime) ? 'application/octet-stream' : $mime[0];
- header("Content-Type: $mime");
- header('Content-Transfer-Encoding: binary');
-
- // Send headers necessary to invoke a "Save As" dialog
- header('Content-Disposition: attachment; filename="'.$filename.'"');
-
- // Prevent caching
- header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
-
- $pragma = 'no-cache';
- $cachecontrol = 'no-cache, max-age=0';
-
- // request::user_agent('browser') seems bugged
- if (request::user_agent('browser') === 'Internet Explorer'
- || stripos(request::user_agent(), 'msie') !== false
- || stripos(request::user_agent(), 'internet explorer') !== false)
- {
- if (request::protocol() === 'https') {
- // See http://support.microsoft.com/kb/323308/en-us
- $pragma = 'cache';
- $cachecontrol = 'private';
-
- } else if (request::user_agent('version') <= '6.0') {
- $pragma = '';
- $cachecontrol = 'must-revalidate, post-check=0, pre-check=0';
- }
- }
-
- header('Pragma: '.$pragma);
- header('Cache-Control: '.$cachecontrol);
- }
-}
-
-class proofsheet_PDF extends FPDF {
-
- /**
- * Print text (header, footer, or caption) with link, formatted as in cfg.
- * It converts UTF-8 back to CP1252, which is used by FPDF.
- * This will trim formatted text to fit and add ellipsis if needed.
- */
- function printText($text, $font, $x, $y, $w, $h, $link = null) {
- $ellipsis = '…'; // ASCII character 133
- // Convert from UTF-8 back to CP1252
- $text = iconv('utf-8','cp1252',$text);
- // Set color, font, and position
- $this->SetTextColor($font['r'],$font['g'],$font['b']);
- $this->SetFont($font['name'],$font['style'],$font['size']);
- $this->SetXY($x, $y);
- // Trim text if needed
- if (($this->GetStringWidth($text)) > $w) {
- // Keep trimming until the size, with ellipsis, is small enough
- while (($this->GetStringWidth($text.$ellipsis)) > $w) {
- $text = substr($text,0,strlen($text)-1);
- }
- // Add the ellipsis to the shortened text
- $text = $text.$ellipsis;
- }
- // Create text cell
- $this->Cell($w,$h,$text,0,0,$font['posn'],false,$link);
- }
-
- /**
- * Print image. This is basically a wrapper around the FPDF image function,
- * except that it determines the file type independent of the file extension
- * and automatically resizes to main aspect ratio within the defined space.
- * Note that this provides robustness for images with incorrect filenames, such
- * as missing_movie.png being called a jpg when copied as a thumbnail in v3.0.2.
- */
- function printImage($imagePath, $x, $y, $w, $h, $link = null, $cfgImageMissing) {
- $imageInfo = getimagesize($imagePath); // [0]=w, [1]=h, [2]=type (1=GIF, 2=JPG, 3=PNG)
- // Figure out the filetype
- switch($imageInfo[2]) {
- case 3:
- $imageType = 'PNG';
- break;
- case 2:
- $imageType = 'JPG';
- break;
- case 1:
- if ($cfgImageMissing['GDflag']) {
- $imageType = 'GIF';
- break;
- }
- default:
- // use the missing image icon instead
- $imagePath = $cfgImageMissing['iconPath'];
- $imageType = $cfgImageMissing['iconType'];
- $imageInfo = $cfgImageMissing['iconInfo'];
- }
- // Determine image orientation and create image
- $ratioWH = ($imageInfo[0]/$w) / ($imageInfo[1]/$h);
- if ($ratioWH>1) {
- $this->image($imagePath, $x, $y+(1-1/$ratioWH)*$h/2, $w, 0, $imageType, $link);
- } else {
- $this->image($imagePath, $x+(1-$ratioWH)*$w/2, $y, 0, $h, $imageType, $link);
- }
- }
-}
+is_album()) {
+ throw new Kohana_Exception('container is not an album: '.$container->relative_path());
+ }
+
+ $pdfname = (empty($container->name))
+ ? 'Gallery.pdf' // @todo purified_version_of($container->title).'.pdf'
+ : $container->name.'.pdf';
+ $headerText = $container->title;
+ $headerLink = $container->abs_url();
+ break;
+
+ case "tag":
+ // @todo: if the module is not installed, it crash
+ $container = ORM::factory("tag", $id);
+ if (is_null($container->name)) {
+ throw new Kohana_Exception('container is not a tag: '.$id);
+ }
+
+ $pdfname = $container->name.'.pdf';
+ $headerText = $container->name;
+ //$headerLink = $container->abs_url();
+ $headerLink = url::abs_site("tag/{$container->id}/" . urlencode($container->name));
+ break;
+
+ default:
+ throw new Kohana_Exception('unhandled container type: '.$container_type);
+ }
+ $files = $this->getFilesList($container);
+
+ /**
+ * Configure PDF file. These are all of the parameters that are used to
+ * format the proof sheet. If you'd like to tweak the formatting, here's
+ * where to do it.
+ */
+ switch($page_type) {
+ case "ltr":
+ // Setup for LTR 8.5" x 11" paper (215.9mm x 279.4mm)
+ $cfg = array(
+ 'pageW' => 215.9, // mm
+ 'pageH' => 279.4, // mm
+ 'imageNumW' => 5, // integer number
+ 'imageNumH' => 5, // integer number
+ 'imageSizeW' => 36, // mm
+ 'imageSizeH' => 36, // mm
+ 'marginL' => 10, // mm
+ 'marginR' => 10, // mm
+ 'marginT' => 21, // mm (header goes in here)
+ 'marginB' => 20, // mm (footer goes in here)
+ 'headerSpace' => 2, // mm (header to top row of images and to link icon)
+ 'footerSpace' => 2, // mm (bottom row of captions to footer)
+ 'captionSpace' => 1, // mm (bottom of image to caption)
+ 'headerFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 14, // pt
+ 'style' => 'B', // combo of B, I, U
+ 'posn' => 'L', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 0),// Blue 0-255
+ 'footerFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 12, // pt
+ 'style' => 'B', // combo of B, I, U
+ 'posn' => 'R', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 0),// Blue 0-255
+ 'captionFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 8, // pt
+ 'style' => 'U', // combo of B, I, U
+ 'posn' => 'C', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 255),// Blue 0-255
+ );
+ break;
+ case "a4":
+ // Setup for A4 210mm x 297mm paper (8.27" x 11.69")
+ $cfg = array(
+ 'pageW' => 210, // mm
+ 'pageH' => 297, // mm
+ 'imageNumW' => 5, // integer number
+ 'imageNumH' => 6, // integer number
+ 'imageSizeW' => 36, // mm
+ 'imageSizeH' => 36, // mm
+ 'marginL' => 8, // mm
+ 'marginR' => 8, // mm
+ 'marginT' => 19, // mm (header goes in here)
+ 'marginB' => 18, // mm (footer goes in here)
+ 'headerSpace' => 2, // mm (header to top row of images and to link icon)
+ 'footerSpace' => 2, // mm (bottom row of captions to footer)
+ 'captionSpace' => 1, // mm (bottom of image to caption)
+ 'headerFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 14, // pt
+ 'style' => 'B', // combo of B, I, U
+ 'posn' => 'L', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 0),// Blue 0-255
+ 'footerFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 12, // pt
+ 'style' => 'B', // combo of B, I, U
+ 'posn' => 'R', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 0),// Blue 0-255
+ 'captionFont' => array(
+ 'name' => 'Arial', // included are Arial/Helvetica, Courier, Times, Symbol, ZapfDingbats
+ 'size' => 8, // pt
+ 'style' => 'U', // combo of B, I, U
+ 'posn' => 'C', // combo of L, C, R
+ 'r' => 0, // Red 0-255
+ 'g' => 0, // Green 0-255
+ 'b' => 255),// Blue 0-255
+ );
+ break;
+ default:
+ throw new Kohana_Exception('unhandled page type: '.$page_type);
+ }
+
+ // Here are some other parameters that need defining
+ $cfg['footerTextPage'] = 'Page '; // Note that this text isn't autofixed by translate module
+ $cfg['footerTextSlash'] = ' / ';
+ $cfg['headerLinkIconPath'] = MODPATH . 'proofsheet/images/ico-link.png';
+ $cfgImageMissing['iconPath'] = MODPATH . 'proofsheet/images/image_missing.png';
+ $cfgImageMissing['iconType'] = 'PNG'; // PNG or JPG is most robust, GIF okay only if GD is installed
+ $pt2mm = 25.4/72; // 25.4mm=1in=72pt
+
+ // Derive a bunch more parameters. These are all dependent on the above stuff.
+ $cfg['headerH'] = $pt2mm * $cfg['headerFont']['size'];
+ $cfg['footerH'] = $pt2mm * $cfg['footerFont']['size'];
+ $cfg['captionH'] = $pt2mm * $cfg['captionFont']['size'];
+ $cfg['imageSpaceW'] = ($cfg['pageW']-$cfg['marginL']-$cfg['marginR']-$cfg['imageNumW']*$cfg['imageSizeW']) / ($cfg['imageNumW']-1);
+ $cfg['imageSpaceH'] = ($cfg['pageH']-$cfg['marginT']-$cfg['marginB']-$cfg['imageNumH']*$cfg['imageSizeH']-$cfg['captionH']-$cfg['captionSpace']) / ($cfg['imageNumH']-1);
+ $linkInfo = getimagesize($cfg['headerLinkIconPath']);
+ $cfg['headerLinkH'] = $cfg['headerH']; // I'm defining this to be the same as the text, but you can change it here.
+ $cfg['headerLinkW'] = $linkInfo[0] / $linkInfo[1] * $cfg['headerLinkH'];
+ $cfg['headerW'] = $cfg['pageW']-$cfg['marginL']-$cfg['marginR']-$cfg['headerLinkW']-$cfg['headerSpace'];
+ $cfg['footerW'] = $cfg['pageW']-$cfg['marginL']-$cfg['marginR'];
+ $cfg['captionW'] = $cfg['imageSizeW']; // I'm defining this to be the same as the image, but you can change it here.
+ $cfg['headerX'] = $cfg['marginL'];
+ $cfg['headerLinkX'] = $cfg['marginL']+$cfg['headerW'];
+ $cfg['footerX'] = $cfg['marginL'];
+ $cfg['headerY'] = $cfg['marginT']-$cfg['headerH']-$cfg['headerSpace'];
+ $cfg['headerLinkY'] = $cfg['marginT']-$cfg['headerLinkH']-$cfg['headerSpace'];
+ $cfg['footerY'] = $cfg['pageH']-$cfg['marginB']+$cfg['footerSpace'];
+ $cfg['imageNum'] = $cfg['imageNumW']*$cfg['imageNumH'];
+ $cfgImageMissing['iconInfo'] = getimagesize($cfgImageMissing['iconPath']);
+ $cfgImageMissing['GDflag'] = graphics::detect_toolkits()->gd->installed; // FPDF uses GD to convert GIFs
+
+ /**
+ * Initialize and build PDF... the main routine. Note that almost all of the
+ * useful configuration parameters are already defined above.
+ */
+
+ // Initialize PDF, disable automatic margins and page breaks
+ $pdf = new proofsheet_PDF('P', 'mm', array($cfg['pageW'],$cfg['pageH']) );
+ $pdf->SetMargins(0,0);
+ $pdf->SetAutoPageBreak(0);
+
+ // Build the PDF
+ $numpages = floor(count($files)/$cfg['imageNum'])+1;
+ $i = 0;
+ foreach($files as $f_path => $f_info) {
+ // Initialize new pages, add header and footer
+ if (($i % $cfg['imageNum'])==0) {
+ $pdf->AddPage();
+ $pdf->printText($headerText, $cfg['headerFont'], $cfg['headerX'], $cfg['headerY'], $cfg['headerW'], $cfg['headerH']);
+ $pdf->printImage($cfg['headerLinkIconPath'], $cfg['headerLinkX'], $cfg['headerLinkY'], $cfg['headerLinkW'], $cfg['headerLinkH'], $headerLink, $cfgImageMissing);
+ $footerText = $cfg['footerTextPage'] . strval(floor($i/$cfg['imageNum'])+1) . $cfg['footerTextSlash'] . strval($numpages);
+ $pdf->printText($footerText, $cfg['footerFont'], $cfg['footerX'], $cfg['footerY'], $cfg['footerW'], $cfg['footerH']);
+ }
+ // Add thumbnail and caption
+ $x = $cfg['marginL'] + ($cfg['imageSizeW']+$cfg['imageSpaceW']) * ( $i % $cfg['imageNumW']);
+ $y = $cfg['marginT'] + ($cfg['imageSizeH']+$cfg['imageSpaceH']) * (floor($i/$cfg['imageNumW']) % $cfg['imageNumH']);
+ $pdf->printImage($f_path, $x, $y, $cfg['imageSizeW'], $cfg['imageSizeH'], null, $cfgImageMissing);
+ $pdf->printText($f_info['name'], $cfg['captionFont'], $x, $y+$cfg['imageSizeH']+$cfg['captionSpace'], $cfg['captionW'], $cfg['captionH'], $f_info['url']);
+ // Increment index and loop
+ $i++;
+ }
+
+ /**
+ * Output the PDF file. I wrote it in two versions (one should always be commented out).
+ */
+ // Using a method similar to downloadalbum
+ $pdfstring = $pdf->Output('','S');
+ $this->prepareOutput();
+ $this->sendHeaders($pdfname, strlen($pdfstring));
+ echo $pdfstring;
+
+ // Using FPDF directly
+ //$pdf->Output($pdfname,'I');
+
+ }
+
+ /**
+ * Return the files that must be included in the archive.
+ * This is largely borrowed from downloadalbum, but does have
+ * significant modifications.
+ */
+ private function getFilesList($container) {
+ $files = array();
+
+ if( $container instanceof Item_Model && $container->is_album() ) {
+ $items = $container->viewable()
+ ->descendants(null, null, array(array("type", "<>", "album")));
+
+ foreach($items as $i) {
+ if (!access::can('view_full', $i)) {
+ continue;
+ }
+
+ $thumb_realpath = realpath($i->thumb_path());
+ if (!is_readable($thumb_realpath)) {
+ continue;
+ }
+
+ $files[$thumb_realpath] = array('url' => $i->abs_url(), 'name' => $i->title);
+ }
+
+ } else if( $container instanceof Tag_Model ) {
+ $items = $container->items();
+ foreach($items as $i) {
+ if (!access::can('view_full', $i)) {
+ continue;
+ }
+
+ if( $i->is_album() ) {
+ foreach($this->getFilesList($i) as $f_name => $f_info) {
+ $files[$f_name] = $f_info;
+ }
+
+ } else {
+ $thumb_realpath = realpath($i->thumb_path());
+ if (!is_readable($thumb_realpath)) {
+ continue;
+ }
+
+ $files[$thumb_realpath] = array('url' => $i->abs_url(), 'name' => $i->title);
+
+ }
+ }
+ }
+
+ if (count($files) === 0) {
+ throw new Kohana_Exception('no thumb files in ['.$container->name.']');
+ }
+
+ return $files;
+ }
+
+
+ /**
+ * See system/helpers/download.php
+ * This is borrowed from downloadalbum without changes.
+ */
+ private function prepareOutput() {
+ // Close output buffers
+ Kohana::close_buffers(FALSE);
+ // Clear any output
+ Event::add('system.display', create_function('', 'Kohana::$output = "";'));
+ }
+
+ /**
+ * See system/helpers/download.php
+ * This is borrowed from downloadalbum without changes.
+ */
+ private function sendHeaders($filename, $filesize = null) {
+ if (!is_null($filesize)) {
+ header('Content-Length: '.$filesize);
+ }
+
+ // Retrieve MIME type by extension
+ $mime = Kohana::config('mimes.'.strtolower(substr(strrchr($filename, '.'), 1)));
+ $mime = empty($mime) ? 'application/octet-stream' : $mime[0];
+ header("Content-Type: $mime");
+ header('Content-Transfer-Encoding: binary');
+
+ // Send headers necessary to invoke a "Save As" dialog
+ header('Content-Disposition: attachment; filename="'.$filename.'"');
+
+ // Prevent caching
+ header('Expires: Thu, 01 Jan 1970 00:00:00 GMT');
+
+ $pragma = 'no-cache';
+ $cachecontrol = 'no-cache, max-age=0';
+
+ // request::user_agent('browser') seems bugged
+ if (request::user_agent('browser') === 'Internet Explorer'
+ || stripos(request::user_agent(), 'msie') !== false
+ || stripos(request::user_agent(), 'internet explorer') !== false)
+ {
+ if (request::protocol() === 'https') {
+ // See http://support.microsoft.com/kb/323308/en-us
+ $pragma = 'cache';
+ $cachecontrol = 'private';
+
+ } else if (request::user_agent('version') <= '6.0') {
+ $pragma = '';
+ $cachecontrol = 'must-revalidate, post-check=0, pre-check=0';
+ }
+ }
+
+ header('Pragma: '.$pragma);
+ header('Cache-Control: '.$cachecontrol);
+ }
+}
+
+class proofsheet_PDF extends FPDF {
+
+ /**
+ * Print text (header, footer, or caption) with link, formatted as in cfg.
+ * It converts UTF-8 back to CP1252, which is used by FPDF.
+ * This will trim formatted text to fit and add ellipsis if needed.
+ */
+ function printText($text, $font, $x, $y, $w, $h, $link = null) {
+ $ellipsis = '…'; // ASCII character 133
+ // Convert from UTF-8 back to CP1252
+ $text = iconv('utf-8','cp1252',$text);
+ // Set color, font, and position
+ $this->SetTextColor($font['r'],$font['g'],$font['b']);
+ $this->SetFont($font['name'],$font['style'],$font['size']);
+ $this->SetXY($x, $y);
+ // Trim text if needed
+ if (($this->GetStringWidth($text)) > $w) {
+ // Keep trimming until the size, with ellipsis, is small enough
+ while (($this->GetStringWidth($text.$ellipsis)) > $w) {
+ $text = substr($text,0,strlen($text)-1);
+ }
+ // Add the ellipsis to the shortened text
+ $text = $text.$ellipsis;
+ }
+ // Create text cell
+ $this->Cell($w,$h,$text,0,0,$font['posn'],false,$link);
+ }
+
+ /**
+ * Print image. This is basically a wrapper around the FPDF image function,
+ * except that it determines the file type independent of the file extension
+ * and automatically resizes to main aspect ratio within the defined space.
+ * Note that this provides robustness for images with incorrect filenames, such
+ * as missing_movie.png being called a jpg when copied as a thumbnail in v3.0.2.
+ */
+ function printImage($imagePath, $x, $y, $w, $h, $link = null, $cfgImageMissing) {
+ $imageInfo = getimagesize($imagePath); // [0]=w, [1]=h, [2]=type (1=GIF, 2=JPG, 3=PNG)
+ // Figure out the filetype
+ switch($imageInfo[2]) {
+ case 3:
+ $imageType = 'PNG';
+ break;
+ case 2:
+ $imageType = 'JPG';
+ break;
+ case 1:
+ if ($cfgImageMissing['GDflag']) {
+ $imageType = 'GIF';
+ break;
+ }
+ default:
+ // use the missing image icon instead
+ $imagePath = $cfgImageMissing['iconPath'];
+ $imageType = $cfgImageMissing['iconType'];
+ $imageInfo = $cfgImageMissing['iconInfo'];
+ }
+ // Determine image orientation and create image
+ $ratioWH = ($imageInfo[0]/$w) / ($imageInfo[1]/$h);
+ if ($ratioWH>1) {
+ $this->image($imagePath, $x, $y+(1-1/$ratioWH)*$h/2, $w, 0, $imageType, $link);
+ } else {
+ $this->image($imagePath, $x+(1-$ratioWH)*$w/2, $y, 0, $h, $imageType, $link);
+ }
+ }
+}
diff --git a/3.0/modules/proofsheet/helpers/proofsheet_event.php b/3.0/modules/proofsheet/helpers/proofsheet_event.php
index 3b772515..1f463c9b 100644
--- a/3.0/modules/proofsheet/helpers/proofsheet_event.php
+++ b/3.0/modules/proofsheet/helpers/proofsheet_event.php
@@ -17,32 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
*/
-
-/**
- * Generate a PDF proof sheet on-the-fly of the current album or tag.
- * By Shad Laws. Version 5, 2012/04/05
- *
- * 2012/04/05, version 5
- * Added ability to include GIF thumbnails if GD is installed (FPDF uses GD)
- * Changed behavior of unhandled file types - now provides missing image icon instead of throwing an exception
- * 2012/03/30, version 4
- * Major rewrite. Output is similar, but everything "under the hood" is much cleaner and (I hope) more easily understood and tweakable by other users.
- * Header link is now an icon.
- * Fixed encoding problems with diacritic marks and special characters.
- * Now includes FPDF as a library instead of requiring a separate installtion.
- * 2012/03/28, version 3
- * Made sizing configuration more flexible
- * Prettified code so it's easier to understand and tweak as desired
- * Added header link
- * First version properly documented and linked to Gallery wiki
- * 2012/03/27, version 2
- * Determines jpg/png type by file header, not extension, which makes it robust against misnamed extensions
- * (N.B.: there's a bug in some movie modules that copy missing_movie.png as a jpg thumbnail!)
- * Made caption size limits to prevent overrun
- * 2012/03/27, version 1
- * Initial release
- */
-
class proofsheet_event_Core {
/**
diff --git a/3.0/modules/proofsheet/module.info b/3.0/modules/proofsheet/module.info
index fec62944..e0debcf6 100644
--- a/3.0/modules/proofsheet/module.info
+++ b/3.0/modules/proofsheet/module.info
@@ -1,6 +1,6 @@
name = "ProofSheet"
description = "Displays links to generate a PDF proof sheet of the current album in A4 or LTR size."
-version = 5
+version = 7
author_name = "Shad Laws"
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:proofsheet"
diff --git a/3.0/modules/register/controllers/admin_register.php b/3.0/modules/register/controllers/admin_register.php
index f88bca30..1362a72b 100755
--- a/3.0/modules/register/controllers/admin_register.php
+++ b/3.0/modules/register/controllers/admin_register.php
@@ -35,11 +35,17 @@ class Admin_register_Controller extends Admin_Controller {
$post->add_rules("policy", "required");
$post->add_rules("group", array($this, "passthru"));
$post->add_rules("email_verification", array($this, "passthru"));
+ // added Shad Laws, v2
+ $post->add_rules("admin_notify", array($this, "passthru"));
+ $post->add_rules("subject_prefix", array($this, "passthru"));
$group_list = array();
if ($post->validate()) {
module::set_var("registration", "policy", $post->policy);
module::set_var("registration", "default_group", $post->group);
module::set_var("registration", "email_verification", !empty($post->email_verification));
+ // added Shad Laws, v2
+ module::set_var("registration", "admin_notify", !empty($post->admin_notify));
+ module::set_var("registration", "subject_prefix", $post->subject_prefix);
message::success(t("Registration defaults have been updated."));
@@ -108,6 +114,12 @@ class Admin_register_Controller extends Admin_Controller {
if (empty($admin->email)) {
module::set_var("registration", "email_verification", false);
}
+ // below lines added Shad Laws, v2
+ $v->content->disable_admin_notify =
+ empty($admin->email) || $form["policy"] !== "admin_approval" ? "disabled" : "";
+ if (empty($admin->email)) {
+ module::set_var("registration", "admin_notify", false);
+ }
$v->content->group_list = array();
foreach (identity::groups() as $group) {
@@ -134,7 +146,10 @@ class Admin_register_Controller extends Admin_Controller {
private function _get_form() {
$form = array("policy" => module::get_var("registration", "policy"),
"group" => module::get_var("registration", "default_group"),
- "email_verification" => module::get_var("registration", "email_verification"));
+ "email_verification" => module::get_var("registration", "email_verification"),
+ // added Shad Laws, v2
+ "subject_prefix" => module::get_var("registration", "subject_prefix"),
+ "admin_notify" => module::get_var("registration", "admin_notify"));
$errors = array_fill_keys(array_keys($form), "");
return array($form, $errors);
diff --git a/3.0/modules/register/controllers/register.php b/3.0/modules/register/controllers/register.php
index 35064b9a..ea8eaef5 100755
--- a/3.0/modules/register/controllers/register.php
+++ b/3.0/modules/register/controllers/register.php
@@ -51,9 +51,15 @@ class register_Controller extends Controller {
} else if ($pending_user->state == 1) {
site_status::warning(
t("There are pending user registration.
if (!empty($group_list)): ?>
diff --git a/3.0/modules/register/views/confirm_registration.html.php b/3.0/modules/register/views/confirm_registration.html.php
index 51fed168..80c62937 100644
--- a/3.0/modules/register/views/confirm_registration.html.php
+++ b/3.0/modules/register/views/confirm_registration.html.php
@@ -1,17 +1,18 @@
- = t("User registration confirmation") ?>
+ = ($subject_prefix.$subject) ?>
- = t("User registration confirmation") ?>
+ = $subject ?>
- = t("Hello, %name,", array("name" => $user->full_name ? $user->full_name : $user->name)) ?>
+ = t("Hello %name,", array("name" => $user->full_name ? $user->full_name : $user->name, "locale" => $locale)) ?>
- = t("We received a request to to create a user with this email. If you made this request, you can confirm it by clicking this link. If you didn't request this password reset, it's ok to ignore this mail.",
+ = t("We received a request to to create a user with this email. If you made this request, you can confirm it by clicking this link. If you didn't request this password reset, it's ok to ignore this mail.",
array("site_url" => html::mark_clean(url::base(false, "http")),
- "confirm_url" => $confirm_url)) ?>
+ "confirm_url" => $confirm_url,
+ "locale" => $locale)) ?>
diff --git a/3.0/modules/register/views/register_admin_notify.html.php b/3.0/modules/register/views/register_admin_notify.html.php
new file mode 100644
index 00000000..39cd04d8
--- /dev/null
+++ b/3.0/modules/register/views/register_admin_notify.html.php
@@ -0,0 +1,15 @@
+
+
+
+ = ($subject_prefix.$subject) ?>
+
+
+ = $subject ?>
+
+ = t("There's a new pending user registration from %name.
You can access the site by clicking this link, after which you can review and approve this request.",
+ array("name" => $user->full_name ? $user->full_name : $user->name,
+ "locale" => $locale,
+ "site_url" => html::mark_clean($admin_register_url))) ?>
+
+
+
diff --git a/3.0/modules/register/views/register_welcome.html.php b/3.0/modules/register/views/register_welcome.html.php
index b2744641..2d18385b 100644
--- a/3.0/modules/register/views/register_welcome.html.php
+++ b/3.0/modules/register/views/register_welcome.html.php
@@ -1,16 +1,17 @@
- = t("Welcome to Gallery3") ?>
+ = ($subject_prefix.$subject) ?>
- = t("Welcome") ?>
+ = $subject ?>
- = t("Hello, %name,", array("name" => $user->full_name ? $user->full_name : $user->name)) ?>
+ = t("Hello %name,", array("name" => $user->full_name ? $user->full_name : $user->name, "locale" => $locale)) ?>
- = t("The user account you requested as been created.
You can access the site by clicking this link and you will be prompted to set your password at this point.",
- array("site_url" => html::mark_clean($site_url))) ?>
+ = t("The user account you requested as been created.
You can access the site by clicking this link and you will be prompted to set your password at this point.",
+ array("site_url" => html::mark_clean($site_url),
+ "locale" => $locale)) ?>
diff --git a/3.0/modules/short_search_fix/helpers/MY_search.php b/3.0/modules/short_search_fix/helpers/MY_search.php
index 8e4b8830..aaf99645 100644
--- a/3.0/modules/short_search_fix/helpers/MY_search.php
+++ b/3.0/modules/short_search_fix/helpers/MY_search.php
@@ -23,36 +23,101 @@ class search extends search_Core {
* few terms in the query.
*/
static function add_query_terms($q) {
- $MAX_TERMS = 5;
-
+ $MAX_TERMS = 5; // used to limit the max number of extra terms
+ $prefix = module::get_var("short_search_fix","search_prefix"); // short search fix prefix
// strip leading, trailing, and extra whitespaces
$terms = preg_replace('/^\s+/', '', $q);
$terms = preg_replace('/\s+$/', '', $terms);
$terms = preg_replace('/\s\s+/', ' ', $terms);
-
- $terms = explode(" ", $terms, $MAX_TERMS);
- //$terms = explode(" ", $q, $MAX_TERMS); // commented out from original function
- for ($i = 0; $i < min(count($terms), $MAX_TERMS - 1); $i++) {
- // Don't wildcard quoted or already wildcarded terms
- if ((substr($terms[$i], 0, 1) != '"') && (substr($terms[$i], -1, 1) != "*")) {
- $terms[] = rtrim($terms[$i], "s") . "*";
+ // explode terms, initialize the loop
+ $terms = explode(" ", $terms); // array
+ $termsextra = ""; // string, not array
+ $numtermsextra = 0;
+ $flagwild = 1;
+ $countquote = 0;
+ $countparen = 0;
+ // run the loop for each term
+ foreach ($terms as &$term) {
+ $countprefix = 0;
+ $countsuffix = 0;
+ $flagopenparen = 0;
+ $flagcloseparen = 0;
+ // set flagwild to 0 if we're over MAX_TERMS (only runs if we're not in the middle of parens/quotes)
+ if ($countparen == 0 && $countquote == 0 && ($numtermsextra >= ($MAX_TERMS - 1))) {
+ $flagwild = 0;
+ }
+ // find opening special characters
+ while ((substr($term, $countprefix, 1) == "(" ||
+ substr($term, $countprefix, 1) == '"' ||
+ substr($term, $countprefix, 1) == "+" ||
+ substr($term, $countprefix, 1) == "-" ||
+ substr($term, $countprefix, 1) == "~" ||
+ substr($term, $countprefix, 1) == "<" ||
+ substr($term, $countprefix, 1) == ">") &&
+ ($countprefix+$countsuffix) < strlen($term)) {
+ if (substr($term, $countprefix, 1) == '"') {
+ $countquote++;
+ $flagwild = 0;
+ }
+ if (substr($term, $countprefix, 1) == "(") {
+ $countparen++;
+ $flagopenparen = 1;
+ }
+ $countprefix++;
+ }
+ // reset flagwild to 1 if we're under MAX_TERMS (only runs if we're not in the middle of quotes, and forced to run if we're still in paren)
+ if ($countquote == 0 && ($countparen > 0 || $numtermsextra < ($MAX_TERMS - 1))) {
+ $flagwild = 1;
+ }
+ // find closing special characters
+ while ((substr($term, -$countsuffix-1, 1) == ")" ||
+ substr($term, -$countsuffix-1, 1) == '"') &&
+ ($countprefix+$countsuffix) < strlen($term)) {
+ if (substr($term, -$countsuffix-1, 1) == '"') {
+ $countquote = max(0, $countquote-1);
+ }
+ if (substr($term, -$countsuffix-1, 1) == ")") {
+ $countparen = max(0, $countparen-1);
+ $flagcloseparen = 1;
+ }
+ $countsuffix++;
+ }
+ // split term
+ $termprefix = substr($term, 0, $countprefix);
+ $termterm = substr($term."A", $countprefix, -$countsuffix-1); // artificial padded A assures that the third argument is always negative
+ $termsuffix = substr($term, -$countsuffix, $countsuffix);
+ // add extra terms with wildcards
+ if ($flagwild == 1 &&
+ substr($termterm, -1, 1) != "*" &&
+ strlen($termterm) > 0) {
+ // @todo: make this i18n friendly with the plural character (only works here with s)
+ $termsextra = $termsextra . $termprefix . $prefix . rtrim($termterm, "s") . "*" . $termsuffix . " ";
+ $numtermsextra++;
+ } elseif ($flagopenparen == 1 && $flagcloseparen == 0) {
+ $termsextra = $termsextra . str_replace('"', '', $termprefix);
+ } elseif ($flagopenparen == 0 && $flagcloseparen == 1) {
+ $termsextra = preg_replace('/\s+$/', '', $termsextra) . ") ";
+ }
+ // add short search prefixes
+ if (strlen($termterm) > 0) {
+ $term = $termprefix . $prefix . $termterm . $termsuffix;
}
}
- //return implode(" ", $terms); // commented out from original function
-
- /**
- * Add the search prefix to the start of every word.
- */
- $prefix = module::get_var("short_search_fix","search_prefix");
+ // implode terms, trim termsextra trailing space (if it exists)
$terms = implode(" ", $terms);
- $terms = preg_replace('/^\s+/', '', $terms); // the implode seems to add this back in
- // add the prefixes
- if (preg_match('/\w/',$terms) > 0) {
- $terms = ' ' . $terms;
- $terms = str_replace(' ', ' '.$prefix, $terms);
- $terms = str_replace(' '.$prefix.'"', ' '.'"'.$prefix, $terms);
- $terms = substr($terms,1);
+ $termsextra = preg_replace('/\s+$/', '', $termsextra);
+ // add extra closing quotes and parentheses
+ while ($countquote > 0) {
+ $terms = $terms.'"';
+ $termsextra = $termsextra.'"';
+ $countquote--;
}
- return $terms;
+ while ($countparen > 0) {
+ $terms = $terms.")";
+ $termsextra = $termsextra.")";
+ $countparen--;
+ }
+ // all done!
+ return ($terms." ".$termsextra);
}
-}
+}
\ No newline at end of file
diff --git a/3.0/modules/short_search_fix/module.info b/3.0/modules/short_search_fix/module.info
index b24d10d2..e9d95782 100644
--- a/3.0/modules/short_search_fix/module.info
+++ b/3.0/modules/short_search_fix/module.info
@@ -1,6 +1,6 @@
name = "Short Search Fix"
description = "Allows 2-3 letter searches to be performed without requiring SQL system variable modification (useful for shared hosting)."
-version = 1
+version = 2
author_name = "Shad Laws"
author_url = ""
info_url = "http://codex.gallery2.org/Gallery3:Modules:short_search_fix"
diff --git a/3.0/modules/tag_cloud_html5/controllers/admin_tag_cloud_html5.php b/3.0/modules/tag_cloud_html5/controllers/admin_tag_cloud_html5.php
index e6a6a766..b724720c 100644
--- a/3.0/modules/tag_cloud_html5/controllers/admin_tag_cloud_html5.php
+++ b/3.0/modules/tag_cloud_html5/controllers/admin_tag_cloud_html5.php
@@ -29,111 +29,88 @@ class Admin_Tag_Cloud_Html5_Controller extends Admin_Controller {
$cfg = $this->_get_config();
$form = $this->_get_admin_form();
if ($form->validate()) {
- if ($form->options_general->load_defaults->value) {
+ if ($form->general->reset_defaults->value) {
// reset all to defaults, redirect with message
module::install("tag_cloud_html5");
message::success(t("Tag cloud options reset successfully"));
url::redirect("admin/tag_cloud_html5");
- } else {
- $valid = true;
- // run checks on various inputs
- $options_general = $form->options_general;
- if ($options_general->height_sidebar->value < 0) {
- $form->options_general->height_sidebar->add_error("not_valid", 1);
- $valid = false;
- }
- foreach ($cfg['groups'] as $groupname => $grouptext) {
- ${"options".$groupname} = $form->{"options".$groupname};
- if ($options_general->{"maxtags".$groupname}->value < 0) {
- $form->options_general->{"maxtags".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if (${"options".$groupname}->{"maxSpeed".$groupname}->value < 0) {
- $form->{"options".$groupname}->{"maxSpeed".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if ((${"options".$groupname}->{"initialX".$groupname}->value < -1) || (${"options".$groupname}->{"initialX".$groupname}->value > 1)) {
- $form->{"options".$groupname}->{"initialX".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if ((${"options".$groupname}->{"initialY".$groupname}->value < -1) || (${"options".$groupname}->{"initialY".$groupname}->value > 1)) {
- $form->{"options".$groupname}->{"initialY".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if ((${"options".$groupname}->{"deadZone".$groupname}->value < 0) || (${"options".$groupname}->{"deadZone".$groupname}->value > 1)) {
- $form->{"options".$groupname}->{"deadZone".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if (${"options".$groupname}->{"zoom".$groupname}->value < 0) {
- $form->{"options".$groupname}->{"zoom".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if ((${"options".$groupname}->{"depth".$groupname}->value < 0) || (${"options".$groupname}->{"depth".$groupname}->value > 1)) {
- $form->{"options".$groupname}->{"depth".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if (${"options".$groupname}->{"outlineOffset".$groupname}->value < 0) {
- $form->{"options".$groupname}->{"outlineOffset".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if (preg_match("/^#[0-9A-Fa-f]{6}$/", ${"options".$groupname}->{"outlineColour".$groupname}->value) == 0) {
- $form->{"options".$groupname}->{"outlineColour".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if ((preg_match("/^#[0-9A-Fa-f]{6}$/", ${"options".$groupname}->{"textColour".$groupname}->value) == 0) && (strcmp(${"options".$groupname}->{"textColour".$groupname}->value, "") != 0) ) {
- $form->{"options".$groupname}->{"textColour".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- if (${"options".$groupname}->{"textHeight".$groupname}->value < 0) {
- $form->{"options".$groupname}->{"textHeight".$groupname}->add_error("not_valid", 1);
- $valid = false;
- }
- }
- if ($valid) {
- // all inputs passed tests above; save them
- module::set_var("tag_cloud_html5", "show_wholecloud_link", ($options_general->show_wholecloud_link->value == 1));
- module::set_var("tag_cloud_html5", "show_add_tag_form", ($options_general->show_add_tag_form->value == 1));
- module::set_var("tag_cloud_html5", "height_sidebar", $options_general->height_sidebar->value);
- module::set_var("tag_cloud_html5", "show_wholecloud_list", ($options_general->show_wholecloud_list->value == 1));
- foreach ($cfg['groups'] as $groupname => $grouptext) {
- module::set_var("tag_cloud_html5", "maxtags".$groupname, $options_general->{"maxtags".$groupname}->value);
-
- $optionsarray = array();
- $optionsarray['maxSpeed'] = ${"options".$groupname}->{"maxSpeed".$groupname}->value;
- $optionsarray['deadZone'] = ${"options".$groupname}->{"deadZone".$groupname}->value;
- $optionsarray['initial'] = array(${"options".$groupname}->{"initialX".$groupname}->value, ${"options".$groupname}->{"initialY".$groupname}->value);
- $optionsarray['initialDecel'] = (${"options".$groupname}->{"initialDecel".$groupname}->value == 1);
- $optionsarray['zoom'] = ${"options".$groupname}->{"zoom".$groupname}->value;
- $optionsarray['depth'] = ${"options".$groupname}->{"depth".$groupname}->value;
- $optionsarray['outlineMethod'] = ${"options".$groupname}->{"outlineMethod".$groupname}->value;
- $optionsarray['outlineOffset'] = ${"options".$groupname}->{"outlineOffset".$groupname}->value;
- $optionsarray['outlineColour'] = ${"options".$groupname}->{"outlineColour".$groupname}->value;
- $optionsarray['textColour'] = ${"options".$groupname}->{"textColour".$groupname}->value;
- $optionsarray['textFont'] = ${"options".$groupname}->{"textFont".$groupname}->value;
- $optionsarray['textHeight'] = ${"options".$groupname}->{"textHeight".$groupname}->value;
- $optionsarray['frontSelect'] = (${"options".$groupname}->{"frontSelect".$groupname}->value == 1);
- $optionsarray['wheelZoom'] = false; // note that this is locked - otherwise scrolling through the page screws everything up
- module::set_var("tag_cloud_html5", "options".$groupname, json_encode($optionsarray));
- }
- // all done; redirect with message
- message::success(t("Tag cloud options updated successfully"));
- url::redirect("admin/tag_cloud_html5");
- }
}
+ // save the new inputs
+ module::set_var("tag_cloud_html5", "show_wholecloud_link", ($form->general->show_wholecloud_link->value == 1));
+ module::set_var("tag_cloud_html5", "show_add_tag_form", ($form->general->show_add_tag_form->value == 1));
+ module::set_var("tag_cloud_html5", "show_wholecloud_list", ($form->general->show_wholecloud_list->value == 1));
+ foreach ($cfg['groups'] as $groupname => $grouptext) {
+ module::set_var("tag_cloud_html5", "maxtags".$groupname, $form->{"size".$groupname}->{"maxtags".$groupname}->value);
+ module::set_var("tag_cloud_html5", "width".$groupname, $form->{"size".$groupname}->{"width".$groupname}->value);
+ module::set_var("tag_cloud_html5", "height".$groupname, $form->{"size".$groupname}->{"height".$groupname}->value);
+
+ $optionsarray = array();
+ // group size
+ $optionsarray['shape'] = $form->{"size".$groupname}->{"shape".$groupname}->value;
+ $optionsarray['zoom'] = $form->{"size".$groupname}->{"zoom".$groupname}->value;
+ $optionsarray['stretchX'] = $form->{"size".$groupname}->{"stretchX".$groupname}->value;
+ $optionsarray['stretchY'] = $form->{"size".$groupname}->{"stretchY".$groupname}->value;
+ // group motion
+ $optionsarray['maxSpeed'] = $form->{"motion".$groupname}->{"maxSpeed".$groupname}->value;
+ $optionsarray['minSpeed'] = $form->{"motion".$groupname}->{"minSpeed".$groupname}->value;
+ $optionsarray['deadZone'] = $form->{"motion".$groupname}->{"deadZone".$groupname}->value;
+ $optionsarray['decel'] = $form->{"motion".$groupname}->{"decel".$groupname}->value;
+ $optionsarray['initial'] = array($form->{"motion".$groupname}->{"initialX".$groupname}->value, $form->{"motion".$groupname}->{"initialY".$groupname}->value);
+ $optionsarray['maxInputZone'] = $form->{"motion".$groupname}->{"maxInputZone".$groupname}->value;
+ // group select
+ $optionsarray['outlineMethod'] = $form->{"select".$groupname}->{"outlineMethod".$groupname}->value;
+ $optionsarray['outlineOffset'] = $form->{"select".$groupname}->{"outlineOffset".$groupname}->value;
+ $optionsarray['outlineColour'] = $form->{"select".$groupname}->{"outlineColour".$groupname}->value;
+ $optionsarray['frontSelect'] = ($form->{"select".$groupname}->{"frontSelect".$groupname}->value == 1);
+ // group appearance
+ $optionsarray['textHeight'] = $form->{"appearance".$groupname}->{"textHeight".$groupname}->value;
+ $optionsarray['textColour'] = $form->{"appearance".$groupname}->{"textColour".$groupname}->value;
+ $optionsarray['textFont'] = $form->{"appearance".$groupname}->{"textFont".$groupname}->value;
+ $optionsarray['depth'] = $form->{"appearance".$groupname}->{"depth".$groupname}->value;
+ // options that are not explicitly defined in admin menu
+ $optionsarray['wheelZoom'] = false; // otherwise scrolling through the page screws everything up (was a problem in v1)
+ $optionsarray['initialDecel'] = true; // this was an option in v4, but it's sorta useless - use minSpeed for a related but better effect
+ $optionsarray['physModel'] = true; // this is the big enhancement for v5, and is a major modification that I did to TagCanvas
+ switch ($optionsarray['shape']) {
+ case "hcylinder":
+ // keep it horizontal - lock x-axis rotation
+ $optionsarray['lock'] = "x";
+ break;
+ case "vcylinder":
+ // keep it vertical - lock y-axis rotation
+ $optionsarray['lock'] = "y";
+ break;
+ default:
+ // do not lock either axis
+ $optionsarray['lock'] = "";
+ }
+ module::set_var("tag_cloud_html5", "options".$groupname, json_encode($optionsarray));
+ }
+ // all done; redirect with message
+ message::success(t("Tag cloud options updated successfully"));
+ url::redirect("admin/tag_cloud_html5");
}
- // print screen from existing form - you wind up here if something wasn't validated
+ // not valid - print screen from existing form
$this->_print_screen($form);
}
private function _get_config() {
// these define the two variable name groups, along with their labels which are always shown with t() for i18n.
- $cfg['groups'] = array("_sidebar"=>"Sidebar", "_wholecloud"=>"Whole cloud");
+ $cfg['groups'] = array("_sidebar"=>t("Sidebar"), "_wholecloud"=>t("Whole cloud"));
// this defines the separator that's used between the group name and the attribute, and is *not* put through t().
- $cfg['sep'] = ": ";
+ $cfg['sep'] = " : ";
+ // this is used in the labels of the width/height parameters
+ $cfg['size'] = array("_sidebar"=>t("as fraction of sidebar width, e.g. 'g-block-content' class"), "_wholecloud"=>t("as fraction of browser window height"));
return $cfg;
}
private function _print_screen($form) {
+ // this part is a bit of a hack, but Forge doesn't seem to allow set_attr() for groups.
+ $form = $form->render();
+ $form = preg_replace("/