pepebe
6/17/2014 - 1:35 PM

a2z - refurbished siteAtoZ snippet

a2z - refurbished siteAtoZ snippet

<?php
/**
 * a2z snippet
 * @author pepebe info@pepebe.de 
 * @version 0.0.1
 * 06/17/2014
 *
 * Refurbished version of siteAtoZ snippet by bobray.
 *
 * Usage:
 * ------
 * 1. Download and install siteAToZ from the repo.
 * 2. Create a new snippet "a2z" and use it instead off siteAToZ.
 *
 * Documentation:
 * None for now, BUT you can find a tutorial for siteAToZ here:
 * http://bobsguides.com/siteatoz-tutorial.html
 * Most of whats explained there is still true for a2z.
 *
 * Credits:
 * --------
 * This snippet was inspired by the work of
 * bobray, garryn, patricksamshire, and OpenGeek
 *
 * Changelog:
 * ----------
 * 0.0.1  - Added additional templating options to script, 
 *        - removed &useJS and &cssFile parameters
 * 
 * 2do list:
 * Remove all dependencies from original siteAToZ package.
 */
 
/** This snippet makes use of getResources to list records alphabetically, with an A to Z header of links to anchors in the text.
 *
 * By far the best practice to get it working is to call getResources directly with
 * a snippet tag in a resource. Once you get that working, and it shows every resource
 * you want to index, just change "getResources" to "SiteAtoZ" in the snippet tag.
 * Once that's working, you can add any of the optional parameters listed below.
 *
 * All of the parameters for getResources will be passed through. They can be used
 * to select the parents, sort field, tpl for each entry, etc.
 *
 * The &resources parameter can only be used to exclude resources (&resources=`-12,19`),
 * using it to include docs not work because getResources will include those resources
 * regardless of any other criteria and they will be included in every alphabet section.
 * The &where parameter will be ignored because it interferes with the selection by initial letter.
 *
 * Simple use:
 * [[!SiteAtoZ? &parents=`6` &tpl=`MyTpl`]]
 *
 * Required parameters:
 * ---------------
 * @property parents - (string) Comma-separated list of ID's of container documents you want included (`0` for all docs).
 * @property tpl - (string) Tpl chunk used to format each entry; Default 'AzItemTpl'.
 *
 * Optional parameters:
 * ---------------
 * @property useNumbers - (boolean) Put a number array in front of the alphabet; default '0'.
 * @property combineNumbers (boolean) Group 0-9 titles together; default '0'.
 * @property useAlphabet - (boolean) Use the Alphabet; default: '1'.
 * @property headingSeparator - (string) Separator to use between letters in heading; Default '&nbsp|&nbsp;'.
 * @property alphabetHeadingStart - (string) Letter to start with; Default: 'A'.
 * @property alphabetHeadingEnd - (string) Letter to end with; Default 'Z'.
 * @property title - (string) Field to used for search; Default: pagetitle.
 * @property headingLinksTpl - (string) A tpl containing the entire A-Z heading (useful if you'd like to use images).
 * @property noData - (string) String to show if search comes up empty.
 *
 * All other parameters are those of getResources. They should all work as they do for getResources with two exceptions:
 * @property resources can be used to exclude documents (e.g., &resources=`-2,24`), but not to include them .
 * @property where will be ignored (it conflicts with the selection by initial letter).
 */

    /* These two lines allow the snippet to run in development environments if the two system settings exist -- do not change or remove them */
    $azAssetsUrl =  $modx->getOption('az_base_url', null, $modx->getOption('assets_url') . 'components/siteatoz/');
    $azAssetsPath =  $modx->getOption('az_base_path', null, $modx->getOption('assets_path') . 'components/siteatoz/');
    
    $output = '';
    $header = array();
    
    /* save some typing */
    $sp =& $scriptProperties;
    
    $documentId = $modx->resource->get('id');
    
    /* 
        tpl - Set Tpl chunk to use for each individual item 
        
        available placeholders:
        -----------------------------------
        You can use all placeholders you could use in getResources.
    
    */
    $sp['tpl'] = !empty($tpl)? $tpl : 'AzItemTpl';

    /* 
        letterTpl - Inner Wrapper around a particicular letter
        
        available placeholders:
        -----------------------------------
        [[+total]]   = total number of items for this letter
        [[+letter]]  = the current letter
        [[+results]] = items found for this letter
        [[+i]]       = autoincrement. Starts with 1
    */
    
    $letterTpl  = !empty($letterTpl)  ? $letterTpl  : '@INLINE <h4>[[+letter]]</h4><ol>[[+results]]</ol>';
    
    /*
        wrapperTpl - Outer wrapper around the full list of results
        
        available placeholders:
        ------------------------------------
        [[+total]]  = total number of items in the whole list of results
        [[+output]] = alphabetically paginated list of all results
    */
    
    $wrapperTpl = !empty($wrapperTpl) ? $wrapperTpl : '@INLINE [[+results]]'; 

    /* -----------------------------------------------------------------------------------

        Example using bootstrap collapsible module
    
        &tpl=`a2z_tpl`
            <li>
                <a href="[[~[[+id]]]]" target="_blank">
                    [[+pagetitle]] [[+longtitle:notempty=` - [[+longtitle]]`]]
                </a>
            </li>
    
        &letterTpl=`a2z_letter_tpl`
        
            <div class="panel-heading">
                <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse_[[+letter]]">
                        [[+letter]]
                        <span class="pull-right"># [[+total]]</span>
                    </a>
                </h4>
            </div>
        
            <div id="collapse_[[+letter]]" class="panel-collapse collapse [[+i:is=`1`:then=`in`:else=``]]">
                <div class="panel-body">';
                    <ol>            
                        [[+results]]
                    </ol>            
                </div>
            </div>

        &wrapperTpl=`a2z_letter_wrapperTpl`
        
            <h3>Memebers</h3>
            <p>Complete list of our [[+total]] members</p>
            
            <div id="accordion" class="panel-group">
                <div class="panel panel-default">
                    [[+output]]
                </div>
            </div>
    ----------------------------------------------------------------------------------- */
    
    /* Set other options */
    $sp['parents'] = empty($sp['parents'])? '0' : $sp['parents'];
    $sp['noData'] = empty($sp['noData'])? 'Sorry, No Resources were Retrieved.' : $sp['noData'];
    $headingSeparator = empty($sp['headingSeparator'])? '<span class="az-separator">&nbsp;|&nbsp;</span></div>'. "\n" : $sp['headingSeparator'] . "</span></div>\n";
    $title = empty($sp['title'])? 'pagetitle' : $sp['title'];
    $alphabetHeadingStart = (empty($sp['alphabetHeadingStart']))? 'A' : $sp['alphabetHeadingStart'];
    $alphabetHeadingEnd = (empty($sp['alphabetHeadingEnd']))? 'Z' : $sp['alphabetHeadingEnd'];
    $useNumbers = $sp['useNumbers'] === '1'? true : false;
    $combineNumbers = $sp['combineNumbers'] === '1'? true : false;
    $useAlphabet = $sp['useAlphabet'] === '0'? false: true;

    /*  Wheter or not the results should be returned in a placeholder or not */
    
    $ph = !empty($ph) ? $ph : false;
    
    
    
    if ($combineNumbers) {
        $n = array('[0-9]');
    } else {
        $n = range('0','9');
    }
    $a = range($alphabetHeadingStart, $alphabetHeadingEnd);
    $alphabet = array();
    
    if ($useNumbers) {
        $alphabet=$n;
    }
    if ($useAlphabet) {
        $alphabet = array_merge($alphabet,$a);
    }
    unset($n,$a);
    
    $whereProperty = !empty($sp['where'])? $sp['where'] : false;
    
    $i = 0;
    $total = 0;
    $sum = 0;
    
    $noData = true;
    foreach ($alphabet as $k=>$v) {
        if ($combineNumbers && ($v == '[0-9]') ) {
            $local_where = array(
                $title . ':REGEXP' => '^[0-9]',
            );
        } else {
            $local_where = array(
                $title . ':LIKE' => $v . '%',
            );
        }

        $sp['where'] = $modx->toJSON($local_where);
    
        $ret = $modx->runSnippet('getResources',$sp);
        if (empty($ret)) {
            $header[] = '        <div class="az-no-results">' . $v;
        } else {
            $noData = false; /* found at least one */

            $i++;
            
            $total = $modx->getPlaceholder('total');
            $sum = $sum + $total;
            
            $header[] = '';
            
            $props = array();
            $props['total']   = $total;
            $props['letter']  = $v;
            $props['results'] = $ret;
            $props['i']       = $i;
            
            $output .= $modx->getChunk($letterTpl ,$props);
        }
    }
    if ($noData === true) {
        $modx->setPlaceholder('noData',$sp['noData']);
        
        $output = $sp['noData'];
    }
    $headingLinks = (empty($sp['headingLinksTpl']))? implode($headingSeparator,$header) : $modx->getChunk($sp['headingLinksTpl']);
    
    $props = array();
    $props['output'] = $output;
    $props['total']  = $sum;
    
    $results = $modx->getChunk($wrapperTpl,$props);
    
    if($ph){
        $modx->toPlaceholder($ph,$results);
        return;
    }
    else{
        return $results;
    }