Coded something up in Couch in an interesting way? Have a snippet or shortcode to share? Post it here for the community to benefit.
45 posts Page 4 of 5
I will try to post the solution tonight. Sorry for inconvenience!
Hello again. :D Hopefully you solved this already :roll: , but I'll post the solution anyway for the rest of us.

:idea:

A multiple input requires brackets after name as in below (copying from limitless kit). So we can't use standard couch-powered inputs yet.
<input type='file' name='multi[]' accept='image/*' id="multi" class="file-input-advanced" multiple="multiple" data-show-preview="false" />

I'm posting a sample editable for multi-uploading images, so paste this in template. If you need any other files - that's easy to change with html-standard "accept" filter.
Code: Select all
    <cms:repeat '3' startcount='0' >
        <cms:editable name="img_<cms:show k_count />"
                      required='0'
                      allowed_ext='jpg, jpeg, png, gif'
                      max_size='20000'
                      type='securefile'
                      label='Bilde'
                      desc="<cms:add k_count '1' />"
                      width='200'
                      height='200'
                      crop='1'
                      quality='90'
            order="100<cms:show k_count />"
                      />
    </cms:repeat>

1. I hope editable definition is straightforward, as it closely follows the one in couch docs. The only interesting part is dynamic creation of 3 editables by repeating them automatically. Kinda saves copypasting, but won't hurt if you have all of them typed in separately, of course. Just saves the hassle if there are 20 possible files to upload..

So, we gonna let user upload 3 files at once -> then the form submits ->then files go into the prepared nest.

A sample button to call the modal:
Code: Select all
<a href="#" data-toggle="modal" data-target="#add" >
    <button type="button" class="btn btn-default"><i class="icon-plus3"></i></button>
</a> 

2017-05-19-153118.png
Modal
2017-05-19-153118.png (10.49 KiB) Viewed 3536 times


A sample of complete HTML for the modal, including the code that will be explained below:
Code: Select all
<cms:set my_template = 'your_template.php' scope='global' />

<div id="add" class="modal fade">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header bg-info">
                <button type="button" class="close" data-dismiss="modal">&times;</button>
                <h5 class="modal-title">Create new record..</h5>
            </div>
            <cms:form
                name='create_record'
                masterpage=my_template
                mode='create'
                enctype='multipart/form-data'
                method='post'
                anchor='0'
                >

                <cms:if k_success >
                        <cms:db_persist_form
                            _invalidate_cache='1'
                            _auto_title="1"
                            />

                        <cms:if k_success >
                            <cms:set_flash name='success' value='1' />
                            <cms:redirect url="<cms:link masterpage=my_template />" />
                        </cms:if>
                </cms:if>

                <cms:if k_error >
                    <cms:set_flash name='alert' value='1' />
                </cms:if>

                <div class="modal-body">

                    <div class="row">
                        <div class="col-md-12">

                            <legend class="text-bold">Add up to 3 pictures</legend>
                            <div class="form-group">

                                <input type='hidden' name='input_multiple'  value='multi' />
                                <input type='hidden' name='securefile_mask' value='img_' />
                                <input type='hidden' name='submit' />

                                <input type='file' name='multi[]' accept='image/*' id="multi" class="file-input-advanced" multiple="multiple" data-show-preview="false" />
                                <cms:hide>
                                    <cms:repeat '3' startcount='0' >
                                        <cms:input type='bound' name="img_<cms:show k_count />"  />
                                    </cms:repeat>
                                </cms:hide>

                            </div>

                        </div>
                    </div>

                </div>

                <div class="modal-footer">
                    <button type="button" class="btn btn-link" data-dismiss="modal">Dismiss</button>
                    <button type="submit" name='submit' class="btn btn-primary">Create<i class="icon-arrow-right14 position-right"></i></button>
                </div>

            </cms:form>

        </div>
    </div>
</div>


Extra code explanation.
1. We gonna indicate the name of our html input, which will be used: <input type='hidden' name='input_multiple' value='multi' />
2. We gonna indicate the name prefix of the editable that we defined: <input type='hidden' name='securefile_mask' value='img_' />. If your editables will be called as file_1, file_2 etc, then change to value='file_'
3. Indicate that form is submitted. Used to make it all work <input type='hidden' name='submit' />.
4. Next, goes our multiple input.
5. Following is a hidden part, that is necessary to create hidden spots for "data-bound" inputs. These are couchcms system inputs that are mandatory for each bound input. Since we have defined our own input for multi-selection of images, then we gonna hide bound inputs, but still those are mandatory, as representatives of all our defined editables.
So, if there are 20 files to upload max at once, there must be 20 hidden bound inputs. This is handled by changing the number in cms:repeat, just the same trick as in defining editables.. OF course name prefix must match.
Code: Select all
<cms:hide>
   <cms:repeat '3' startcount='0' >
         <cms:input type='bound' name="img_<cms:show k_count />"  />
   </cms:repeat>
</cms:hide>


That's it for the HTML part.

Now php part.
When the form submits, we must take the flow into our hands before CouchCMS gets to it.
Paste a line above all lines in the template. We gonna call our silly php script.
Code: Select all
<?php include 'upload-multi-basic.php'; ?>
<?php require_once( 'cms/cms.php' ); ?>


Here is what we need to do: we must reformat the way our files got submitted by default into the way Couch understands them.
Regular HTML form submits the file and PHP by itself arranges the uploading to a temp folder and does everything that we don't need to touch. It normally puts info to its array $_FILES. We can see what's inside of POST and FILES by logging like this:
Code: Select all
error_log( print_r($_POST, true));
error_log( print_r($_FILES, true));

Nothing fancy, but we can check the FILES array, which at the start looks like this for a sample png file:
Code: Select all
    [multi] => Array
        (
            [name] => Array
                (
                    [0] => 2017-05-19-153118.png
                )
            [type] => Array
                (
                    [0] => image/png
                )
            [tmp_name] => Array
                (
                    [0] => D:\CloudOne\OpenServer\userdata\temp\phpCB41.tmp
                )
            [error] => Array
                (
                    [0] => 0
                )
            [size] => Array
                (
                    [0] => 10745
                )
        )

But for Couch we must make it look like this:
Code: Select all
    [f_img_0] => Array
        (
            [name] => 2017-05-19-153118.png
            [type] => image/png
            [tmp_name] => D:\CloudOne\OpenServer\userdata\temp\phpCB41.tmp
            [error] => 0
            [size] => 10745
        )

Having done that, we are all set. So just by changing the look of array we can make uploading work. :)

Create and empty file "input-multi-basic.php". It will have this code and nothing else:
Code: Select all
<?php

if( !isset( $_POST['input_multiple'] ) || !isset( $_POST['securefile_mask'] ) ) return;

if( isset( $_FILES[$_POST['input_multiple']] ) ){

        // Files submitted via multiple input.
        $uploaded = $_FILES[$_POST['input_multiple']];
        $mask = $_POST['securefile_mask'];

        // Count # of uploaded files
        $total = count( $uploaded['name'] );
        $available_spots = array();

        // Loop through existing images to build array of empty spots
        for( $i=0; $i<20; $i++ ){
            if( !isset( $_POST['secure_file_id_f_' . $mask . $i] ) ){
                $available_spots[] = $i;
            }
        }

        $total_spots = count( $available_spots );

        if( $total_spots < $total ){

            $warning = $total_spots;
            $total = $total_spots;

        }

        // Loop through uploaded images
        for( $i=0; $i<$total; $i++ ){

            $empty_spot = $available_spots[$i];

            //Get file info
            $tmpFilePath = $uploaded['tmp_name'][$i];
            $tmpFileName = $uploaded['name'][$i];
            $tmpFileMime = $uploaded['type'][$i];
            $tmpFileSize = $uploaded['size'][$i];
            $tmpFileErro = $uploaded['error'][$i];

            //Make sure we have a filepath, so file is uploaded to server okay
            if( $tmpFilePath && !$tmpFileErro ){

                // make sure format matches the expected by CouchCMS
                $_FILES['f_' . $mask . $empty_spot] = array(
                                        'name' => $tmpFileName,
                                        'type' => $tmpFileMime,
                                        'tmp_name' => $tmpFilePath,
                                        'error' => '0',
                                        'size' => $tmpFileSize );

            }

        }

}


It has a limitation of max 20 uploaded files at once, because I believe it's what PHP has by default as a limit after default installation.

Now it all should work fine. Create a template, list with cms:pages its cloned pages in list-view.
Then form gets submitted with or without attachments and a cloned page gets created in the background. After successful action, there is a redirection in the form again to the list-view, so you can output your images like this:
Code: Select all
<cms:pages masterpage=my_template >
   <h5>Page#<cms:show k_current_record /> @ <cms:show k_page_date /></h5> 
   <p>Attachments:
   <cms:repeat '3' startcount='0' >
        <cms:show_securefile "img_<cms:show k_count />" >               
                <div class="thumbnail">           
                            <div class="thumb">
                                 <img src="<cms:cloak_url link=file_id  />" />                                                                                                                                           
                            </div>
                </div>
         </cms:show_securefile>
    </cms:repeat>       
</cms:pages>


Please report any bugs. This is from real project, so I hope it's working fine for you as well as it did for me.
Don't thank me :D but instead ask for this to be an option in the CMS core :)
Thanks a lot for looking at this! :mrgreen:
I'll try your code in the next days and let you know the results.
@trendoman I played with your piece of code. Well done, it works really nice!!

I just have a few remarks:
    1/ In your post, the php file is named twice "upload-multi-basic.php" and "input-multi-basic.php"
    2/ I struggled a bit with the max number of files that can be uploaded at once. I tested the code as is (with max=3) and wanted to increase the value. I needed to remove the template content and the template itself using the couch admin interface in order to have this max value taken into account...
    3/ I also realized that I had some permission problem on my filesystem (in the directory couchcms/uploads/attachments/). After pressing the button for submitting the files for upload, no new content was created, without any error message... It was ok after fixing the permission.
    4/ I wonder if the php array _FILES[] should be clean up at the end of the file with an unset($_FILES[$_POST['input_multiple']]); to remove this element that is unneccessary to couch

I would definitively vote to have this piece of code integrated into the base code of couchcms. :D
@olivier, thanks.
Your remarks are valuable, thanks.
This piece is very silly, so it won't come straight to couch core code ever. Securefile type of editable is a delicate matter.
I am glad it worked for you fine, and of course you are welcome to unset the unnecessary array - it just never crossed my mind to do that.
I have an issue with the code posted earlier by @trendoman regarding redirection when submitting a form.
Indeed, after submiting the images for upload, I'd like to jump directly to the newly created page, but instead I get form submission page.

I saved trendoman's code into a file called 'gallery.php' and added the (common) list and page view , like this
Code: Select all
<cms:if k_is_page >
  <h4>Page#<cms:show k_current_record /> @ <cms:show k_page_date /> % <cms:show k_page_link/></h4>
  <cms:repeat count=max_image startcount='0' >
    <cms:show_securefile "img_<cms:show k_count />" >
      <!-- show image -->
    </cms:show_securefile>
  </cms:repeat>
<cms:else />
  <cms:pages masterpage='gallery.php' >
    <!-- show list of all galleries -->
    <h4>Page#<cms:show k_current_record /> @ <cms:show k_page_date /> % <cms:show k_page_link/></h4>
  </cms:pages>
  <div id="add" class="modal fade">

    <!-- modal window definition ... -->
    <cms:form
     ...
     >
       <cms:if k_success >
         <cms:db_persist_form
         _invalidate_cache='1'
         _auto_title="1"
         />

         <cms:if k_success >
           <cms:set_flash name='success' value='1' />
           <cms:redirect url="<cms:link masterpage=my_template />" />
         </cms:if>
       </cms:if>

     <!-- ... end of modal window definition ... -->
    </cms:form>
   </div>
</cms:if>

I tried to change the redirect in the <cms:if k_success> by
Code: Select all
<cms:redirect k_page_link />
but it always redirects to the list view...

Am I doing something wrong?
Is there a way to get directly to the page e.g. http://mysite.com/gallery.php?p=XXX, where XXX is the id of the newly cloned page after submitting the form?
Yes, for databound forms in Couch, there is a parameter that offers information about the newly created page.
I found a similar question here viewtopic.php?f=4&t=9901 that got answered. Please refer to it and if any issues arise do let me know.
Cool, a simple
Code: Select all
<cms:redirect url="<cms:show k_template_link/>?p=<cms:show k_last_insert_id />" />
does the trick!

Thank you!
Also can be coded as -
Code: Select all
<cms:redirect url="<cms:link masterpage=my_masterpage page=k_last_insert_page_name />" />

I like <cms:link /> tag, because it supports seo-urls and more parameters (esp. folder).
@trendoman,

I followed your instructions, but I don't know why it doesn't work, can you help me?
I have 2 files.
Uploader.php
Code: Select all
<?php include 'upload-multi-basic.php'; ?>
<?php require_once( 'couch/cms.php' ); ?>
<cms:template title='Uploader' hidden='0' access_level='0' order='1' clonable='1'  >

    <cms:repeat '3' startcount='0' >
        <cms:editable name="img_<cms:show k_count />"
                      required='0'
                      allowed_ext='jpg, jpeg, png, gif'
                      max_size='20000'
                      type='securefile'
                      label='Bilde'
                      desc="<cms:add k_count '1' />"
                      width='200'
                      height='200'
                      crop='1'
                      quality='90'
            order="100<cms:show k_count />"
                      />
    </cms:repeat>
 
</cms:template>

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Limitless - Responsive Web Application Kit by Eugene Kopyov</title>

   <!-- Global stylesheets -->
   <link href="https://fonts.googleapis.com/css?family=Roboto:400,300,100,500,700,900" rel="stylesheet" type="text/css">
   <link href="assets/css/icons/icomoon/styles.css" rel="stylesheet" type="text/css">
   <link href="assets/css/minified/bootstrap.min.css" rel="stylesheet" type="text/css">
   <link href="assets/css/minified/core.min.css" rel="stylesheet" type="text/css">
   <link href="assets/css/minified/components.min.css" rel="stylesheet" type="text/css">
   <link href="assets/css/minified/colors.min.css" rel="stylesheet" type="text/css">
   <!-- /global stylesheets -->

   <!-- Core JS files -->
   <script type="text/javascript" src="assets/js/plugins/loaders/pace.min.js"></script>
   <script type="text/javascript" src="assets/js/core/libraries/jquery.min.js"></script>
   <script type="text/javascript" src="assets/js/core/libraries/bootstrap.min.js"></script>
   <script type="text/javascript" src="assets/js/plugins/loaders/blockui.min.js"></script>
   <!-- /core JS files -->

   <!-- Theme JS files -->
   <script type="text/javascript" src="assets/js/plugins/uploaders/fileinput.min.js"></script>

   <script type="text/javascript" src="assets/js/core/app.js"></script>
   <script type="text/javascript" src="assets/js/pages/uploader_bootstrap.js"></script>
   <!-- /theme JS files -->

</head>

<body>
<cms:set my_template = 'uploader.php' scope='global' />

   <!-- Page container -->
   <div class="page-container">

      <!-- Page content -->
      <div class="page-content">

         <!-- Main content -->
         <div class="content-wrapper">

            <!-- Bootstrap file input -->
            <div class="panel panel-flat">

               <div class="panel-body">
                  <p class="content-group">Bootstrap <code>file input</code> plugin enhances the HTML 5 file input for Bootstrap 3.x into an advanced widget with file preview for various files, multiple selection and more. The plugin enhances these concepts and simplifies the widget initialization with simple HTML markup on a file input. It offers support for previewing a wide variety of files i.e. images, text, html, video, audio, flash, and objects.</p>

                  
                  <cms:form
                name='create_record'
                masterpage=my_template
                mode='create'
                enctype='multipart/form-data'
                method='post'
                anchor='0'
                >

                <cms:if k_success >
                        <cms:db_persist_form
                            _invalidate_cache='1'
                            _auto_title="1"
                            />

                        <cms:if k_success >
                            <cms:set_flash name='success' value='1' />
                            <cms:redirect url="<cms:link masterpage=my_template />" />
                        </cms:if>
                </cms:if>

                <cms:if k_error >
                    <cms:set_flash name='alert' value='1' />
                </cms:if>

                <div class="modal-body">

                    <div class="row">
                        <div class="col-md-12">

                            <legend class="text-bold">Add up to 3 pictures</legend>
                            <div class="form-group">

                                <input type='hidden' name='input_multiple'  value='multi' />
                                <input type='hidden' name='securefile_mask' value='img_' />
                                <input type='hidden' name='submit' />

                                <input type='file' name='multi[]' accept='image/*' id="multi" class="file-input-advanced" multiple="multiple" data-show-preview="false" />
                                <cms:hide>
                                    <cms:repeat '3' startcount='0' >
                                        <cms:input type='bound' name="img_<cms:show k_count />"  />
                                    </cms:repeat>
                                </cms:hide>

                            </div>

                        </div>
                    </div>

                </div>

                <div class="modal-footer">
                    <button type="button" class="btn btn-link" data-dismiss="modal">Dismiss</button>
                    <button type="submit" name='submit' class="btn btn-primary">Create<i class="icon-arrow-right14 position-right"></i></button>
                </div>

            </cms:form>
               </div>
            </div>
            <!-- /bootstrap file input -->

         </div>
         <!-- /main content -->

      </div>
      <!-- /page content -->

   </div>
   <!-- /page container -->

</body>
</html>



<?php COUCH::invoke(); ?>


and 'upload-multi-basic.php' at /couch/snippets/upload-multi-basic.php
Code: Select all
<?php

if( !isset( $_POST['input_multiple'] ) || !isset( $_POST['securefile_mask'] ) ) return;

if( isset( $_FILES[$_POST['input_multiple']] ) ){

        // Files submitted via multiple input.
        $uploaded = $_FILES[$_POST['input_multiple']];
        $mask = $_POST['securefile_mask'];

        // Count # of uploaded files
        $total = count( $uploaded['name'] );
        $available_spots = array();

        // Loop through existing images to build array of empty spots
        for( $i=0; $i<20; $i++ ){
            if( !isset( $_POST['secure_file_id_f_' . $mask . $i] ) ){
                $available_spots[] = $i;
            }
        }

        $total_spots = count( $available_spots );

        if( $total_spots < $total ){

            $warning = $total_spots;
            $total = $total_spots;

        }

        // Loop through uploaded images
        for( $i=0; $i<$total; $i++ ){

            $empty_spot = $available_spots[$i];

            //Get file info
            $tmpFilePath = $uploaded['tmp_name'][$i];
            $tmpFileName = $uploaded['name'][$i];
            $tmpFileMime = $uploaded['type'][$i];
            $tmpFileSize = $uploaded['size'][$i];
            $tmpFileErro = $uploaded['error'][$i];

            //Make sure we have a filepath, so file is uploaded to server okay
            if( $tmpFilePath && !$tmpFileErro ){

                // make sure format matches the expected by CouchCMS
                $_FILES['f_' . $mask . $empty_spot] = array(
                                        'name' => $tmpFileName,
                                        'type' => $tmpFileMime,
                                        'tmp_name' => $tmpFilePath,
                                        'error' => '0',
                                        'size' => $tmpFileSize );

            }

        }

}
45 posts Page 4 of 5
cron