<?php
/**
* getResourcesColumns
* @author @sepiariver
*
* &parent optional ID of Resource from which to fetch children. Defaults to current resource.
* &fields optional Resource field(s) from which to fetch values. Defaults to 'pagetitle,longtitle,introtext,parent,hidemenu'.
* &columns optional Number of columns to sort Resources into and wrap with colWrapper_n;
* &columnDirection optionalVertical or horizontal column sorting. Defaults to horizontal
* &depth optional Depth to seek children via getChildIds(). Defaults to 1
* &limit optional Limit number to output. Defaults to 0 (no limit)
* &offset optional Offset to pass to query. Defaults to 0
* &sortBy optional Field to sort by. Defaults to 'publishedon'
* &sortDir optional Sort direction. Defaults to 'DESC'
* &showUnpublished optionalFlag to show unpublished Resources. Defaults to 0
* &showHidden optional Flag to show hidden Resources. Defaults to 0
* &showDeleted optional Flag to show deleted Resources. Defaults to 0
* &hideContainers optional Flag to hide container Resources. Defaults to 0
* &toPlaceholder optional Key of placeholder to which to send output
* &includeTVList optional List of TV names to include in output
* &processTVList optional List of TV names to process for output
* &rowTpl Chunk name to use for each item
* &rowTpl_colN optional Override for rows inside column "N". Defaults to ''
* &colWrapTpl optional Chunk name to use for wrapping each column. Defaults to ''
* &colWrapTpl_colN Override for wrapping columns "N". Defaults to ''
* &rowSeparator optional Separator for each row within a column. Defaults to PHP_EOL
* &colSeparator optional Separator for each column. Defaults to PHP_EOL
* &exclude optional Comma-separated list of Resource IDs, optionally with "-" prefix, to exclude
*
**/
// OPTIONS
$parent = $modx->getOption('parent', $scriptProperties, $modx->resource->get('id'));
// Can't do anything without a parent ID
if (empty($parent) || $parent < 0) {
$modx->log(modX::LOG_LEVEL_ERROR, 'getResourcesColumns requires a parent resource ID');
return '';
}
$fields = array_filter(array_map('trim', explode(',', $modx->getOption('fields', $scriptProperties, 'pagetitle,longtitle,introtext,parent,hidemenu'))));
// If no fields are specified, we would never return anything anyways
if (empty($fields) || (count($fields) === 0)) return '';
$columns = (int) $modx->getOption('columns', $scriptProperties, 2);
// If columns are less than 1, we can't return them
if ($columns < 1) return '';
$colDir = strtolower(substr($modx->getOption('columnDirection', $scriptProperties,'h'), 0, 1));
$depth = $modx->getOption('depth', $scriptProperties, 1);
$limit = $modx->getOption('limit', $scriptProperties, 0);
$offset = $modx->getOption('offset', $scriptProperties, 0);
$sortBy = $modx->getOption('sortBy', $scriptProperties, 0);
$sortDir = $modx->getOption('sortDir', $scriptProperties, 0);
$showUnpublished = $modx->getOption('showUnpublished', $scriptProperties, 0);
$showHidden = $modx->getOption('showHidden', $scriptProperties, 0);
$showDeleted = $modx->getOption('showDeleted', $scriptProperties, 0);
$hideContainers = $modx->getOption('hideContainers', $scriptProperties, 0);
$where = $modx->fromJSON($modx->getOption('where', $scriptProperties, '[]'));
$exclude = array_filter(array_map('trim', explode(',', $modx->getOption('exclude', $scriptProperties, ''))));
$exclude = (is_array($exclude) && !empty($exclude)) ? $exclude : array();
foreach ($exclude as $k => $v) {
$exclude[$k] = trim($v, '-');
}
$rowTpl = $modx->getOption('rowTpl', $scriptProperties, '');
$colWrapTpl = $modx->getOption('colWrapTpl', $scriptProperties, '');
$rowSeparator = $modx->getOption('rowSeparator', $scriptProperties, PHP_EOL);
$colSeparator = $modx->getOption('colSeparator', $scriptProperties, PHP_EOL);
$toPlaceholder = $modx->getOption('toPlaceholder', $scriptProperties, '');
$includeTVList = array_filter(array_map('trim', explode(',', $modx->getOption('includeTVList', $scriptProperties, ''))));
$processTVList = array_filter(array_map('trim', explode(',', $modx->getOption('processTVList', $scriptProperties, ''))));
$tvPrefix = $modx->getOption('tvPrefix', $scriptProperties, 'tv.');
// Get childIds
$resIds = $modx->getChildIds($parent, $depth);
// Query
$c = $modx->newQuery('modResource');
// Criteria
$criteria = array(
'id:IN' => $resIds,
);
if (!$showUnpublished) $criteria['published:='] = 1;
if (!$showHidden) $criteria['hidemenu:='] = 0;
if (!$showDeleted) $criteria['deleted:='] = 0;
if ($hideContainers) $criteria['isfolder:='] = 0;
if (!empty($exclude)) $criteria['id:NOT IN'] = $exclude;
$c->where($criteria);
// Always select pk
$fields = array_merge($fields, array('id'));
// Only take what we need
$c->select($fields);
$c->limit($limit, $offset);
// Support Tagger etc
if (is_array($where) && !empty($where)) $c->where($where);
// Sort
$c->sortby($sortBy, $sortDir);
// Debug only
//$c->prepare();
//return $c->toSQL();
// Get Total Count
$total = $modx->getCount('modResource', $c);
if ($total < 1) return '';
// Fetch Resources
$resources = $modx->getCollection('modResource', $c);
// Calculate columns based on idx
$idx = 0;
if ($colDir === 'v') {
$eachColCount = round($total / $columns);
}
$output = array();
foreach ($resources as $resource) {
// Set current column
$col = ($colDir === 'v') ? (intval($idx / $eachColCount) + 1) : ($idx % $columns) + 1;
// Set TPL
$tpl = (isset($scriptProperties['rowTpl_col' . $col])) ? $scriptProperties['rowTpl_col' . $col] : $rowTpl;
// Get Resource values
$values = $resource->toArray('', false, true); // don't lazy-load
// TODO: Better way to get TV values
if (!empty($includeTVList)) {
$tvc = $modx->newQuery('modTemplateVars');
$tvc->where(array(
'name:IN' => $includeTVList,
));
$tvs = $resource->getMany('TemplateVars', $tvc);
foreach ($tvs as $tv) {
$tvname = $tv->get('name');
$values[$tvPrefix . $tvname] = (in_array($tvname, $processTVList)) ? $tv->renderOutput($id) : $tv->getValue($id);
}
}
// Populate column
$output[$col][] = $modx->getChunk($tpl, $values);
$idx++;
}
foreach ($output as $index => $column) {
// Column output
$columnOutput = implode($rowSeparator, $column);
// Set tpl
$cTpl = (isset($scriptProperties['colWrapTpl_col' . $index])) ? $scriptProperties['colWrapTpl_col' . $index] : $colWrapTpl;
$output[$index] = (!empty($cTpl)) ? $modx->getChunk($cTpl, array('column' => $columnOutput)) : $columnOutput;
}
$output = implode($colSeparator, $output);
if (empty($toPlaceholder)) return $output;
$modx->setPlaceholder($toPlaceholder, $output);