JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
finish responsive images, revamp admin_images
authorJason Woofenden <jason@jasonwoof.com>
Fri, 6 Nov 2015 21:28:27 +0000 (16:28 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Fri, 6 Nov 2015 21:28:27 +0000 (16:28 -0500)
.htaccess
admin_images.html
admin_images.php
admin_pages.html
admin_pages.php
cms_images_autoresize.php [new file with mode: 0644]
config.php
inc/wfpl
style.styl

index 1c77df3..e2884e3 100644 (file)
--- a/.htaccess
+++ b/.htaccess
@@ -23,9 +23,15 @@ php_flag engine off
 RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo
 # code execution exception: allow only /wfpl_main.php
 # <Files> matches regardless of directory/path, so rewrite php in subdirs
 RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo
 # code execution exception: allow only /wfpl_main.php
 # <Files> matches regardless of directory/path, so rewrite php in subdirs
-RewriteRule ^wfpl_main\.php$  - [L]
+RewriteRule ^(wfpl_main\.php|cms_images_autoresize\.php)$  - [L]
 RewriteRule .*\.php$ - [L,R=404]
 <Files "wfpl_main.php">
        php_flag engine on
        SetHandler application/x-httpd-php
 </Files>
 RewriteRule .*\.php$ - [L,R=404]
 <Files "wfpl_main.php">
        php_flag engine on
        SetHandler application/x-httpd-php
 </Files>
+<Files "cms_images_autoresize.php">
+       php_flag engine on
+       SetHandler application/x-httpd-php
+</Files>
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^cms_images/[0-9a-f]+w[0-9]+\.[pj][np]g$ /cms_images_autoresize.php
index 942dc06..f9d7063 100644 (file)
        <!--~display {~-->
                <h1>~$host~ Admin Control Panel</h1>
 
        <!--~display {~-->
                <h1>~$host~ Admin Control Panel</h1>
 
-               <h2><!--~image nonempty {~--><img src="~image thumb_src~" width="~image thumb_width~" height="~image thumb_height~" alt="" style="display: inline-block; vertical-align: middle"><!--~}~--> Details for Image ~caption empty {~~name nonempty {~"~name html~"~}~~}~~caption nonempty {~"~caption html~"~}~</h2>
+               <h2><!--~image nonempty {~--><span class="wfpl_thumb" style="background-image: url(~image image_src_thumb~); vertical-align: middle;"></span><!--~}~--> Details for Image ~caption empty {~~name nonempty {~"~name html~"~}~~}~~caption nonempty {~"~caption html~"~}~</h2>
 
 
-               <p><a href="admin_images?new=1">Add another image</a></p>
-
-               <p><a href="admin_images">Back to images</a></p>
+               <p><a href="admin_images">&larr; Back to images</a></p>
 
                <p><a href="admin_images?edit_id=~id attr~">Edit this image</a></p>
 
 
                <p><a href="admin_images?edit_id=~id attr~">Edit this image</a></p>
 
 
                <p>Now that you've uploaded this image, you can insert it into a page with the <strong>page&nbsp;editor</strong>. You can get to the <strong>page&nbsp;editor</strong> from the <a href="admin">control panel</a> or by going to a page you'd like to edit, then clicking "Edit this page" at the top.</p>
 
 
                <p>Now that you've uploaded this image, you can insert it into a page with the <strong>page&nbsp;editor</strong>. You can get to the <strong>page&nbsp;editor</strong> from the <a href="admin">control panel</a> or by going to a page you'd like to edit, then clicking "Edit this page" at the top.</p>
 
-
-               <h2>Sizes</h2>
-
-               <p>This image is available in the following sizes.</p>
-
-               <p>Note: Currently only the first and last sizes are available in the page editor.</p>
-
-               <!--~smaller {~-->
-                       <div style="margin-top: 25px"><strong>Width: ~width~ pixels, Height: ~height~ pixels</strong></div>
-                       <div style="font-size: 10px"><img src="~src~" alt="" />~caption nonempty {~~caption html~~}~</div>
-               <!--~}~-->
-
                <div style="margin-top: 25px"><strong>Full Size (centered):</strong></div>
                <div style="margin-top: 25px"><strong>Full Size (centered):</strong></div>
-               <div class="wfpl_ic"><img src="~image image_src~" width="~image image_width~" height="~image image_height~" alt="" />~caption nonempty {~~caption html~~}~</div>
-
-               <!--~no_sizes {~-->
-                       <p>To display this image smaller, <a href="admin_images?edit_id=~id attr~">edit this image</a> and enter display size(s).</p>
-               <!--~}~-->
+               <div class="wfpl_ic"><div class="wfpl_i" style="background-image: url(~image image_src_full~); padding-top: ~image image_aspect~"></div>~caption nonempty {~~caption html~~}~</div>
 
 
 
 
 
 
                        <div class="field"><input type="file" name="image"><input type="hidden" name="old_image" value="~image attr~"></div>
 
                        <div class="caption">Name (optional)</div>
                        <div class="field"><input type="file" name="image"><input type="hidden" name="old_image" value="~image attr~"></div>
 
                        <div class="caption">Name (optional)</div>
-                       <div class="field_notes">This name is only displayed on the image administration page.</div>
+                       <div class="field_notes">This name is only displayed on administration pages.</div>
                        <div class="field"><input type="text" name="name" value="~name attr~"></div>
 
                        <div class="caption">Caption (optional)</div>
                        <div class="field_notes">Here's some symbols you might want to paste in: &copy; &nbsp; &mdash; &nbsp; &ndash;</div>
                        <div class="field"><input type="text" name="caption" value="~caption attr~"></div>
 
                        <div class="field"><input type="text" name="name" value="~name attr~"></div>
 
                        <div class="caption">Caption (optional)</div>
                        <div class="field_notes">Here's some symbols you might want to paste in: &copy; &nbsp; &mdash; &nbsp; &ndash;</div>
                        <div class="field"><input type="text" name="caption" value="~caption attr~"></div>
 
-                       <div class="caption">Sizes</div>
-                       <div class="field_notes">(Enter the width and height (in pixels) at which you'd like to use this image. Put an x between them with no spaces, so it looks like this: 100x200. The image will be scaled so it maintains it's aspect ratio (shape) and just fits inside those dimentions. You can use this image at multiple different sizes, by entering a different set of dimensions (WIDTHxHEIGHT) on each line)</div>
-                       <div class="field"><textarea rows="9" cols="22" name="sizes">~sizes html~</textarea></div>
-
-                       <div class="caption">&nbsp;</div>
-                       <div class="field"><input type="submit" name="save" value="Save"></div>
+                       <div class="caption field"><input type="submit" name="save" value="Save"></div>
 
                </form>
 
 
                </form>
 
@@ -96,7 +73,7 @@
                        <table cellspacing="0" cellpadding="4" border="0" summary="" class="evenodd">
                                <tr><th>Image</th><th>Name</th><th>Caption</th><th>&nbsp;</th></tr><!--~listings {~-->
                                <tr>
                        <table cellspacing="0" cellpadding="4" border="0" summary="" class="evenodd">
                                <tr><th>Image</th><th>Name</th><th>Caption</th><th>&nbsp;</th></tr><!--~listings {~-->
                                <tr>
-                                       <td class="listing"><a href="admin_images?id=~id~"><!--~image nonempty {~--><img src="~image thumb_src~" width="~image thumb_width~" height="~image thumb_height~" alt=""><!--~}~--></a></td>
+                                       <td class="listing"><a href="admin_images?id=~id~"><!--~image nonempty {~--><span class="wfpl_thumb" style="background-image: url(~image image_src_thumb~)"></span><!--~}~--></a></td>
                                        <td class="listing"><a href="admin_images?id=~id~">~name html~<!--~name empty {~--><em>(blank)</em><!--~}~--></a></td>
                                        <td class="listing"><a href="admin_images?id=~id~">~caption html~<!--~caption empty {~--><em>(blank)</em><!--~}~--></a></td>
                                        <td><a href="admin_images?admin_images_delete_id=~id~" onclick="return confirm('Permanently delete?')">[delete this image]</a></td>
                                        <td class="listing"><a href="admin_images?id=~id~">~name html~<!--~name empty {~--><em>(blank)</em><!--~}~--></a></td>
                                        <td class="listing"><a href="admin_images?id=~id~">~caption html~<!--~caption empty {~--><em>(blank)</em><!--~}~--></a></td>
                                        <td><a href="admin_images?admin_images_delete_id=~id~" onclick="return confirm('Permanently delete?')">[delete this image]</a></td>
index 3b0fef7..73d16c6 100644 (file)
@@ -4,17 +4,6 @@
 
 define('ADMIN_IMAGES_DB_FIELDS', 'image,name,caption,sizes');
 
 
 define('ADMIN_IMAGES_DB_FIELDS', 'image,name,caption,sizes');
 
-# Set this to the path to your uploads directory. It can be relative to the
-# location of this script. IT MUST END WITH A SLASH
-$GLOBALS['upload_directory'] = 'cms_images/';
-
-$GLOBALS['image_max_width'] = '704';
-$GLOBALS['image_max_height'] = '1900';
-$GLOBALS['image_thumb_max_width'] = '70';
-$GLOBALS['image_thumb_max_height'] = '70';
-$GLOBALS['image_file_name'] = uniqid() . getmypid() . '.jpg'; # comment this out to use uploader's filename
-
-
 require_once(DOCROOT . 'inc/wfpl/format.php');
 require_once(DOCROOT . 'inc/wfpl/upload.php');
 
 require_once(DOCROOT . 'inc/wfpl/format.php');
 require_once(DOCROOT . 'inc/wfpl/upload.php');
 
@@ -37,15 +26,21 @@ function admin_images_get_fields() {
 
        $data['name'] = format_oneline(_REQUEST_cut('name'));
        $data['caption'] = format_oneline(_REQUEST_cut('caption'));
 
        $data['name'] = format_oneline(_REQUEST_cut('name'));
        $data['caption'] = format_oneline(_REQUEST_cut('caption'));
-       $data['sizes'] = str_replace(' ', '', strtolower(format_unix(_REQUEST_cut('sizes'))));
 
 
-       if($_FILES['image'] && $_FILES['image']['error'] == 0) {
-               $data['image'] = convert_uploaded_image('image', $GLOBALS['upload_directory'] . $GLOBALS['image_file_name'], $GLOBALS['image_max_width'], $GLOBALS['image_max_height'], $GLOBALS['image_thumb_max_width'], $GLOBALS['image_thumb_max_height']);
+       if($_FILES['image'] && $_FILES['image']['error'] == 0 && file_exists($_FILES['image']['tmp_name'])) {
+               $image_fn_ext = path_or_mime_to_ext($_FILES['image']['name'], $_FILES['image']['type']);
+               $image_fn_ext = ext_to_web_image_ext($image_fn_ext);
+               $image_fn_base = sha1_file($_FILES['image']['tmp_name']);
+               if (strlen($image_fn_base) == 40) {
+                       $image_fn_base = substr($image_fn_base, 0, 16);
+                       $image_filename = 'cms_images/' . $image_fn_base . '.' . $image_fn_ext;
+                       $data['image'] = convert_uploaded_image('image', $image_filename);
+               }
        } else {
                if(_REQUEST_cut('delete_image') == 'Yes') {
                        $data['image'] = '';
                } else {
        } else {
                if(_REQUEST_cut('delete_image') == 'Yes') {
                        $data['image'] = '';
                } else {
-                       $data['image'] = format_image_w_h_thumb_w_h(_REQUEST_cut('old_image'));
+                       $data['image'] = format_image_w_h(_REQUEST_cut('old_image'));
                }
        }
        unset($_FILES['image']);
                }
        }
        unset($_FILES['image']);
@@ -97,7 +92,7 @@ function admin_images_main_display($id) {
 
        # Find pages that have this image on it
        if($data['image']) {
 
        # Find pages that have this image on it
        if($data['image']) {
-               $references = db_get_assocs('cms_pages', 'title,filename', 'where content like "%%%s%%" order by concat(nav_title,title)', substr(enc_image_src($data['image']), 0, -4)); # FIXME test that this works for smaller images
+               $references = db_get_assocs('cms_pages', 'title,filename', 'where content like "%%%s%%" order by concat(nav_title,title)', substr(enc_image_src($data['image']), 0, -4));
                if($references) {
                        $data['references'] = array(
                                'data' => $references,
                if($references) {
                        $data['references'] = array(
                                'data' => $references,
@@ -105,68 +100,22 @@ function admin_images_main_display($id) {
                }
        }
 
                }
        }
 
-       # display smaller versions with instructions and example code
-       $smaller == array();
-       if($data['image'] && $data['sizes']) {
-               $big_src = enc_image_src($data['image']);
-               $row = explode("\n", $data['sizes']);
-               foreach($row as $max_hw) {
-                       $max_hw = format_width_height($max_hw);
-                       if($max_hw == '') {
-                               continue;
-                       }
-                       list($max_width, $max_height) = explode('x', $max_hw);
-                       $src = str_replace('.', "-$max_width-$max_height.", $big_src);
-                       $dimensions = image_dimensions($src);
-                       if($dimensions) {
-                               list($width, $height) = explode('x', $dimensions);
-                       } else {
-                               $width = $max_width;
-                               $height = $max_height;
-                       }
-
-                       $smaller[] = array(
-                               'src' => $src,
-                               'max_width' => $max_width,
-                               'max_height' => $max_height,
-                               'width' => $width,
-                               'height' => $height);
-               }
-       }
-       if($smaller) {
-               $data['smaller'] = $smaller;
-       } else {
-               tem_set('no_sizes');
-       }
-
        tem_set('display', $data);
 }
 
 function admin_images_main_delete($id) {
        $data = db_get_assoc('cms_images', 'image,sizes', 'where id=%i', $id);
        if ($data) {
        tem_set('display', $data);
 }
 
 function admin_images_main_delete($id) {
        $data = db_get_assoc('cms_images', 'image,sizes', 'where id=%i', $id);
        if ($data) {
-               $filenames = array();
-               $space = strpos($data['image'], ' ');
-               $dot = strpos($data['image'], '.');
-               if ($space !== false && $dot !== false && $dot < $space) {
-                       $base = substr($data['image'], 0, $dot);
-                       $ext = substr($data['image'], $dot, $space - $dot);
-                       $filenames[] = "$base$ext";
-                       $filenames[] = "{$base}_thumb$ext";
-                       $sizes = explode("\n", $data['sizes']);
-                       foreach ($sizes as $max_hw) {
-                               $max_hw = format_width_height($max_hw);
-                               if($max_hw == '') {
-                                       continue;
-                               }
-                               list($max_width, $max_height) = explode('x', $max_hw);
-                               $filenames[] = "$base-{$max_width}x$max_height$ext"; # old naming scheme
-                               $filenames[] = "$base-{$max_width}-$max_height$ext"; # new namich scheme
+               $src = enc_image_src($data['image']);
+               if ($src) {
+                       $filenames = array($src);
+                       foreach ($GLOBALS['wfpl_image_widths'] as $w) {
+                               $filenames [] = substr($src, 0, -4) . 'w' . $w . substr($src, -4);
                        }
                        }
-               }
-               foreach ($filenames as $filename) {
-                       if (file_exists($filename)) {
-                               unlink($filename);
+                       foreach ($filenames as $filename) {
+                               if (file_exists($filename)) {
+                                       unlink($filename);
+                               }
                        }
                }
                db_delete('cms_images', 'where id=%i', $id);
                        }
                }
                db_delete('cms_images', 'where id=%i', $id);
@@ -193,23 +142,6 @@ function admin_images_main_form($id = false) {
                # save anything
                # Note: If you change this to re-display the form in some cases, be sure to handle image uploads well (don't make them upload it again.)
 
                # save anything
                # Note: If you change this to re-display the form in some cases, be sure to handle image uploads well (don't make them upload it again.)
 
-               # resize image as needed
-               if($data['image'] && $data['sizes']) {
-                       $big_src = enc_image_src($data['image']);
-                       $row = explode("\n", $data['sizes']);
-                       foreach($row as $max_hw) {
-                               $max_hw = format_width_height($max_hw);
-                               if($max_hw == '') {
-                                       continue;
-                               }
-                               list($max_width, $max_height) = explode('x', $max_hw);
-                               $src = str_replace('.', "-$max_width-$max_height.", $big_src);
-                               if(($_FILES['image'] && $_FILES['image']['error'] == 0) || !file_exists($src)) {
-                                       imagemagick_convert($big_src, $src, "-geometry $max_hw", 'Resizing image');
-                               }
-                       }
-               }
-
                # save to database
                if($id) {
                        db_update_assoc('cms_images', $data, 'where id=%i', $id);
                # save to database
                if($id) {
                        db_update_assoc('cms_images', $data, 'where id=%i', $id);
index 59af576..c7ac728 100644 (file)
@@ -62,6 +62,8 @@
        <script>
                window.cke_wfpl_images = {
                        images: ~wfpl_images_json~,
        <script>
                window.cke_wfpl_images = {
                        images: ~wfpl_images_json~,
+                       small_width: ~wfpl_image_width_small~,
+                       thumb_width: ~wfpl_image_width_thumb~,
                        next_id: 0,
                        selected: [],
                        editors: []
                        next_id: 0,
                        selected: [],
                        editors: []
@@ -90,7 +92,7 @@
                        var selected = window.cke_wfpl_images.selected[plugin_id];
                        var editor = window.cke_wfpl_images.editors[plugin_id];
                        var image;
                        var selected = window.cke_wfpl_images.selected[plugin_id];
                        var editor = window.cke_wfpl_images.editors[plugin_id];
                        var image;
-                       var code, width, height, src, size, caption;
+                       var code, src, caption;
                        if (selected == null) {
                                CKEDITOR.dialog.getCurrent().hide();
                                return;
                        if (selected == null) {
                                CKEDITOR.dialog.getCurrent().hide();
                                return;
                        image = window.cke_wfpl_images.images[selected];
                        switch(align) {
                                case 'left':
                        image = window.cke_wfpl_images.images[selected];
                        switch(align) {
                                case 'left':
-                                       code = '<span class="wfpl_ifl"'
+                                       code = '<div class="wfpl_li">'
+                               break;
+                               case 'centered':
+                                       code = '<div class="wfpl_ci">'
                                break;
                                case 'right':
                                break;
                                case 'right':
-                                       code = '<span class="wfpl_ifr"'
+                                       code = '<div class="wfpl_ri">'
                                break;
                                break;
-                               case 'centered': case 'full':
-                                       code = '<div class="wfpl_ic"'
+                               case 'full':
+                                       code = '<div class="wfpl_fi">'
                                break;
                        }
                                break;
                        }
-                       size = image.sizes.replace(/^\s+|\s+$/g, '').split(/\s\+/)[0];
-                       width = image.image_width;
-                       height = image.image_height;
-                       src = image.image;
+                       code += '<div class="wfpl_i"'
+                       src = image.src;
                        if (image.caption == '') {
                                caption = '&nbsp;';
                        } else {
                                caption = enc_html(image.caption);
                        }
                        if (align != 'full') {
                        if (image.caption == '') {
                                caption = '&nbsp;';
                        } else {
                                caption = enc_html(image.caption);
                        }
                        if (align != 'full') {
-                               var wh = size.split('x');
-                               wh[0] = parseInt(wh[0]);
-                               wh[1] = parseInt(wh[1]);
-                               if (width / height > wh[0] / wh[1]) {
-                                       height = Math.round(height * wh[0] / width);
-                                       width = wh[0];
-                               } else {
-                                       width = Math.round(width * wh[1] / height);
-                                       height = wh[1];
-                               }
-                               size = '' + wh[0] + '-' + wh[1]; // dash instead of x
-                               src = src.substr(0, src.length - 4) + '-' + size + src.substr(src.length - 4);
+                               src =
+                                       src.substr(0, src.length - 4)
+                                       + 'w' + window.cke_wfpl_images.small_width
+                                       + src.substr(src.length - 4);
                        }
                        }
-                       height += 4;
                        code += ' style="background-image: url(/' + src + ');';
                        code += ' style="background-image: url(/' + src + ');';
-                       code += ' width: ' + width + 'px;';
-                       code += ' padding-top: ' + height + 'px;';
-                       code += '">' + caption;
-                       switch(align) {
-                               case 'left': case 'right':
-                                       code += '</span>'
-                               break;
-                               case 'centered': case 'full':
-                                       code += '</div>'
-                               break;
-                       }
+                       code += ' padding-top: ' + image.aspect;
+                       code += '">&nbsp</div>' + caption;
+                       code += '</div>'
                        CKEDITOR.dialog.getCurrent().hide();
                        CKEDITOR.currentInstance.insertElement(CKEDITOR.dom.element.createFromHtml(code));
                }
                        CKEDITOR.dialog.getCurrent().hide();
                        CKEDITOR.currentInstance.insertElement(CKEDITOR.dom.element.createFromHtml(code));
                }
                                        thumbs = '<div class="cke_wfpl_thumbs">'
                                        for (i in window.cke_wfpl_images.images) {
                                                im = window.cke_wfpl_images.images[i];
                                        thumbs = '<div class="cke_wfpl_thumbs">'
                                        for (i in window.cke_wfpl_images.images) {
                                                im = window.cke_wfpl_images.images[i];
-                                               thumbs += '<div class="'+selected+'cke_wfpl_thumb" onclick="return window.cke_wfpl_images_thumb_click('+plugin_id+', this, '+im.id+')" style="background-image: url('+im.thumb+')">'+ enc_html(im.name.length > 0 ? im.name : im.caption) + '</div>';
+                                               thumbs += '<div class="'+selected+'cke_wfpl_thumb" onclick="return window.cke_wfpl_images_thumb_click('+plugin_id+', this, '+im.id+')" style="background-image: url('+im.src.substr(0, im.src.length - 4) + 'w' + window.cke_wfpl_images.thumb_width + im.src.substr(im.src.length - 4) + ')">'+ enc_html(im.name.length > 0 ? im.name : im.caption) + '</div>';
                                                selected = '';
                                        }
                                        thumbs += '</div>'
                                                selected = '';
                                        }
                                        thumbs += '</div>'
index 9c7f56a..382ff5c 100644 (file)
@@ -75,22 +75,18 @@ function admin_pages_main_delete($id) {
 # get all images from admin_images (for cms)
 function admin_pages_get_images() {
        $out = [];
 # get all images from admin_images (for cms)
 function admin_pages_get_images() {
        $out = [];
-       $rows = db_get_assocs('cms_images', 'image,name,caption,sizes', 'order by name, caption, image');
+       $rows = db_get_assocs('cms_images', 'image,name,caption', 'order by name, caption, image');
        if ($rows) {
        if ($rows) {
-               $id = 0;
-               foreach($rows as &$row) {
+               $id = -1;
+               foreach($rows as &$row) { $id += 1;
                        $parts = explode(' ', $row['image'] . '      ', 7);
                        $out[] = [
                                'id' => '' . $id,
                        $parts = explode(' ', $row['image'] . '      ', 7);
                        $out[] = [
                                'id' => '' . $id,
-                               'thumb' => $parts[3],
-                               'image' => $parts[0],
-                               'image_width' => (int)$parts[1],
-                               'image_height' => (int)$parts[2],
-                               'sizes' => $row['sizes'],
+                               'src' => $parts[0],
+                               'aspect' => ''.(round(100000 * ((int)$parts[2]) / ((int)$parts[1]) / 1000)).'%',
                                'name' => $row['name'],
                                'caption' => $row['caption']
                        ];
                                'name' => $row['name'],
                                'caption' => $row['caption']
                        ];
-                       $id += 1;
                } unset($row);
        }
        return $out;
                } unset($row);
        }
        return $out;
@@ -172,6 +168,8 @@ function admin_pages_main_form($id = false) {
        }
 
        tem_set('wfpl_images_json', json_encode(admin_pages_get_images()));
        }
 
        tem_set('wfpl_images_json', json_encode(admin_pages_get_images()));
+       tem_set('wfpl_image_width_small', WFPL_IMAGE_WIDTH_SMALL);
+       tem_set('wfpl_image_width_thumb', WFPL_IMAGE_WIDTH_THUMB);
        tem_set('form', $data);
        tem_set('$head'); # wysiwyg init goes in <head>
 }
        tem_set('form', $data);
        tem_set('$head'); # wysiwyg init goes in <head>
 }
diff --git a/cms_images_autoresize.php b/cms_images_autoresize.php
new file mode 100644 (file)
index 0000000..922b3cf
--- /dev/null
@@ -0,0 +1,76 @@
+<?php
+
+define('DOCROOT', __DIR__ .'/');
+require_once(DOCROOT . 'config.php');
+require_once(DOCROOT . 'inc/wfpl/upload.php');
+
+function cms_images_autoresize_main_abort_404() {
+       http_response_code('404');
+       header('HTTP/1.0 404 File Not Found');
+       header('Content-Type: text/plain');
+       print('404: File not found');
+       exit();
+}
+
+function cms_images_autoresize_main() {
+       # figure out what file was requested
+       $out_fn = $_SERVER['REDIRECT_URL'];
+       $out_fn = preg_replace('|[?].*|', '', $out_fn); # apache 2.4.17
+       $out_fn = preg_replace('|.*/|', '', $out_fn);
+       $matches = array();
+       if (!preg_match('/^([0-9a-f]+)w([0-9]+)[.](png|jpg)$/', $out_fn, $matches)) {
+               cms_images_autoresize_main_abort_404();
+       }
+
+       $basename = $matches[1];
+       $width = (int)$matches[2];
+       $ext = $matches[3];
+       $in_fn = "$basename.$ext";
+       $in_path = DOCROOT . 'cms_images/' . $in_fn;
+       $out_path = DOCROOT . 'cms_images/' . $out_fn;
+       $lock_path = $out_path . '.lock';
+
+       if (!in_array($width, $GLOBALS['wfpl_image_widths'], true)) {
+               cms_images_autoresize_main_abort_404();
+       }
+
+       if (!file_exists($in_path)) {
+               cms_images_autoresize_main_abort_404();
+       }
+
+       @$lock = fopen($lock_path, 'x');
+       if (!$lock) {
+               # delete lock file if it's stale
+               $s = stat($lock_path);
+               if ($s && $s['mtime'] + 3 < time()) {
+                       unlink($lock_path);
+               } else {
+                       # if it's fresh, exit with temporary error
+                       header('HTTP/1.0 503 Service Unavailable');
+                       header('Content-Type: text/plain');
+                       header('Retry-After: 4');
+                       print("503 Service Unavailable (try again soon)\n");
+                       var_dump($s);
+                       var_dump(time());
+                       exit();
+               }
+       }
+
+       imagemagick_convert($in_path, $out_path,
+               '-geometry '
+               . $width
+               . 'x'
+               . ($width * 2)
+               . "'>'"
+       );
+
+       # done! kill the lock
+       fclose($lock);
+       unlink($lock_path);
+
+       if (!headers_sent()) {
+               header('Content-Type: ' . ($ext = 'jpg' ? 'image/jpeg' : 'image/png'));
+               readfile($out_path);
+       }
+}
+cms_images_autoresize_main();
index f5c078e..e60cbd7 100644 (file)
@@ -9,6 +9,16 @@ define('WFPL_DB_PASS', 'fixme');
 # CMS login passwords are stored in the database. See admin_users.php
 date_default_timezone_set('America/New_York');
 
 # CMS login passwords are stored in the database. See admin_users.php
 date_default_timezone_set('America/New_York');
 
+# If you change these, update style.styl too
+define('WFPL_IMAGE_WIDTH_FULL',  900);
+define('WFPL_IMAGE_WIDTH_SMALL', 336); # this is "sidebar_width" in style.styl
+define('WFPL_IMAGE_WIDTH_THUMB',  70);
+$GLOBALS['wfpl_image_widths'] = array(
+       WFPL_IMAGE_WIDTH_FULL,
+       WFPL_IMAGE_WIDTH_SMALL,
+       WFPL_IMAGE_WIDTH_THUMB
+);
+
 # Enable features, auto-includes
 require_once(DOCROOT . 'inc/wfpl/format.php');
 require_once(DOCROOT . 'inc/wfpl/db.php');
 # Enable features, auto-includes
 require_once(DOCROOT . 'inc/wfpl/format.php');
 require_once(DOCROOT . 'inc/wfpl/db.php');
index eb26817..f8a8d44 160000 (submodule)
--- a/inc/wfpl
+++ b/inc/wfpl
@@ -1 +1 @@
-Subproject commit eb268173999615e857af705883ce8c94c5c039dd
+Subproject commit f8a8d44598bdb6e4446920b8d10d1bc62916c9aa
index e8c5d3d..88d0420 100644 (file)
@@ -9,6 +9,7 @@ golden_ratio_small = 0.38196601125010515180 // ratio of whole to smaller part
 ////////////////
 
 // dimensions (max. these will scale down for smaller screens except in ie8)
 ////////////////
 
 // dimensions (max. these will scale down for smaller screens except in ie8)
+// if you change these, update config.php too
 site_width = 900px
 site_padding = 15px
 sidebar_padding = 20px
 site_width = 900px
 site_padding = 15px
 sidebar_padding = 20px
@@ -237,7 +238,7 @@ footer
 
 
 
 
 
 
-// floating images (from pastable example code on admin_images)
+// obsolete floating images (from pastable example code on admin_images)
 span.wfpl_ifl
        display: block
        float: left
 span.wfpl_ifl
        display: block
        float: left
@@ -319,36 +320,60 @@ table.evenodd
        & + &
                margin-left: 10px
 
        & + &
                margin-left: 10px
 
-.wfpl_fr
+.wfpl_li, .wfpl_ci, .wfpl_ri, .wfpl_fi
        display: block
        display: block
+       margin-bottom: 1%
+       clear: both
+       font-size: 80%
+       text-align: right
+       .wfpl_i
+               display: block
+               width: 100%
+               background-size: 100% auto
+               background-repeat: no-repeat
+               background-position: 50% top
+               margin-bottom: 3px // padding above caption
+               // clip line with &nbsp; (which is there so ckeditor doesn't delete this)
+               height: 0
+               overflow: hidden
+.wfpl_li, .wfpl_ci, .wfpl_ri
+       width: sidebar_width // when window is large
+.wfpl_li
+       float: left
+       margin-right: sidebar_padding
+.wfpl_ci
+       margin-left: auto
+       margin-right: auto
+.wfpl_ri
        float: right
        margin-left: sidebar_padding
        float: right
        margin-left: sidebar_padding
-       margin-bottom: 1%
-       width: sidebar_width // simple when big, and for ie8 (which ignores media queries)
 
 @media screen and (max-width: (content_width / vw_to_content_width))
        #centerer
                width: auto
                margin: 0
                padding: unit(site_padding_pct * 100, '%')
 
 @media screen and (max-width: (content_width / vw_to_content_width))
        #centerer
                width: auto
                margin: 0
                padding: unit(site_padding_pct * 100, '%')
-       .wfpl_fr
+       .wfpl_li, .wfpl_ri
                width: linear_scale_calc(content_width, sidebar_width, sidebar_width, sidebar_width * .5)
                width: linear_scale_calc(content_width, sidebar_width, sidebar_width, sidebar_width * .5)
+       .wfpl_ri
                margin-left: unit(sidebar_padding_pct * 100, '%')
                margin-left: unit(sidebar_padding_pct * 100, '%')
+       .wfpl_li
+               margin-right: unit(sidebar_padding_pct * 100, '%')
 @media screen and (max-width: (sidebar_width / vw_to_content_width))
 @media screen and (max-width: (sidebar_width / vw_to_content_width))
-       .wfpl_fr
+       .wfpl_li, .wfpl_ci, .wfpl_ri
                float: none
                margin-left: 0
                float: none
                margin-left: 0
-               margin-bottom: 0
+               margin-right: 0
                width: 100%
                width: 100%
-.wfpl_fr > .wfpl_i
-       display: block
-       width: 100%
-       height: auto
+
+// does not contain a .wfpl_i
+.wfpl_thumb
+       display: inline-block
+       width: 70px
+       height: 70px;
        background-size: contain
        background-size: contain
+       background-position: 50% 50%
        background-repeat: no-repeat
        background-repeat: no-repeat
-       background-position: 50% top
-       font-size: 80%
-       text-align: right
 
 #mobile_menu_button
        display: none;
 
 #mobile_menu_button
        display: none;