diff --git a/ddGetMultipleField.php b/ddGetMultipleField.php index a6ef9f1..d447e0d 100644 --- a/ddGetMultipleField.php +++ b/ddGetMultipleField.php @@ -1,124 +1,124 @@ config['base_path'].'assets/snippets/ddTools/modx.ddtools.class.php'; + //Если задано имя поля, которое необходимо получить -if (isset($getField)){ - $field = $modx->runSnippet('ddGetDocumentField', array( - 'id' => $getId, - 'field' => $getField - )); +if (isset($docField)){ + $string = ddTools::getTemplateVarOutput(array($docField), $docId); + $string = $string[$docField]; } //Если задано значение поля -if (isset($field) && $field != ""){ - $splY = isset($splY) ? $splY : '||'; - $splX = isset($splX) ? $splX : '::'; +if (isset($string) && strlen($string) > 0){ + if (!isset($rowDelimiter)){$rowDelimiter = '||';} + if (!isset($colDelimiter)){$colDelimiter = '::';} + //Являются ли разделители регулярками - $splYisRegexp = (filter_var($splY, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^\/.*\/[a-z]*$/'))) !== false) ? true : false; - $splXisRegexp = (filter_var($splX, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^\/.*\/[a-z]*$/'))) !== false) ? true : false; - $num = (!isset($num) || !is_numeric($num)) ? '0' : $num; + $rowDelimiterIsRegexp = (filter_var($rowDelimiter, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^\/.*\/[a-z]*$/'))) !== false) ? true : false; + $colDelimiterIsRegexp = (filter_var($colDelimiter, FILTER_VALIDATE_REGEXP, array('options' => array('regexp' => '/^\/.*\/[a-z]*$/'))) !== false) ? true : false; + + if (!isset($startRow) || !is_numeric($startRow)){$startRow = '0';} //Если заданы условия фильтрации - if (!empty($vals)){ + if (isset($filter)){ //Разбиваем по условиям - $temp = explode('||', $vals); + $temp = explode('||', $filter); - $vals = array(); + $filter = array(); foreach ($temp as $val){ //Разбиваем по колонке/значению $val = explode('::', $val); - //Если указали просто значение (значит, это нулевая колонка) + //Если указали просто значение (значит, это нулевая колонка) TODO: Удалить через пару версий. if (count($val) < 2){ $val[1] = $val[0]; $val[0] = '0'; } //Если ни одно правило для этой колонки ещй не задано - if (!isset($vals[$val[0]])){ - $vals[$val[0]] = array(); + if (!isset($filter[$val[0]])){ + $filter[$val[0]] = array(); } //Добавляем правило для соответствующей колонки - $vals[$val[0]][] = $val[1]; + $filter[$val[0]][] = $val[1]; } }else{ - $vals = false; + $filter = false; } - $count = (!isset($count) || !is_numeric($count)) ? 'all' : $count; - $colNum = isset($colNum) ? explode(',', $colNum) : 'all'; + if (!isset($totalRows) || !is_numeric($totalRows)){$totalRows = 'all';} + $columns = isset($columns) ? explode(',', $columns) : 'all'; //Хитро-мудро для array_intersect_key - if (is_array($colNum)) $colNum = array_combine($colNum, $colNum); + if (is_array($columns)){$columns = array_combine($columns, $columns);} $sortDir = isset($sortDir) ? strtoupper($sortDir) : false; - $sortBy = isset($sortBy) ? $sortBy : '0'; - $glueY = isset($glueY) ? $glueY : ''; - $glueX = isset($glueX) ? $glueX : ''; + if (!isset($sortBy)){$sortBy = '0';} + if (!isset($rowGlue)){$rowGlue = '';} + if (!isset($colGlue)){$colGlue = '';} $removeEmptyRows = (isset($removeEmptyRows) && $removeEmptyRows == '0') ? false : true; $removeEmptyCols = (isset($removeEmptyCols) && $removeEmptyCols == '0') ? false : true; - $typographing = (isset($typographing) && $typographing == '1') ? true : false; $urlencode = (isset($urlencode) && $urlencode == '1') ? true : false; - $format = isset($format) ? strtolower($format) : 'html'; - $tplX = isset($tplX) ? explode(',', $tplX) : false; - $resultToPlaceholder = (isset($resultToPlaceholder) && $resultToPlaceholder == '1') ? true : false; + $outputFormat = isset($outputFormat) ? strtolower($outputFormat) : 'html'; + $colTpl = isset($colTpl) ? explode(',', $colTpl) : false; //Разбиваем на строки - $res = $splYisRegexp ? preg_split($splY, $field) : explode($splY, $field); - + $res = $rowDelimiterIsRegexp ? preg_split($rowDelimiter, $string) : explode($rowDelimiter, $string); + //Общее количество строк $total = count($res); //Перебираем строки, разбиваем на колонки foreach ($res as $key => $val){ - $res[$key] = $splXisRegexp ? preg_split($splX, $val) : explode($splX, $val); + $res[$key] = $colDelimiterIsRegexp ? preg_split($colDelimiter, $val) : explode($colDelimiter, $val); //Если необходимо получить какие-то конкретные значения - if ($vals){ + if ($filter !== false){ //Перебираем колонки для фильтрации - foreach ($vals as $col_k => $col_v){ + foreach ($filter as $k => $v){ //Если текущего значения в списке нет, сносим нафиг - if (!in_array($res[$key][$col_k], $col_v)){ + if (!in_array($res[$key][$k], $v)){ unset($res[$key]); //Уходим (строку уже снесли, больше ничего не важно) break; @@ -127,15 +127,15 @@ } //Если нужно получить какую-то конкретную колонку (также проверяем на то, что строка вообще существует, т.к. она могла быть уже удалена ранее) - if ($colNum != 'all' && isset($res[$key])){ + if ($columns != 'all' && isset($res[$key])){ //Выбираем только необходимые колонки + Сбрасываем ключи массива - $res[$key] = array_values(array_intersect_key($res[$key], $colNum)); + $res[$key] = array_values(array_intersect_key($res[$key], $columns)); } //Если нужно удалять пустые строки (также проверяем на то, что строка вообще существует, т.к. она могла быть уже удалена ранее) if ($removeEmptyRows && isset($res[$key])){ //Если строка пустая, удаляем - if (strlen(implode('', $res[$key])) == 0) unset($res[$key]); + if (strlen(implode('', $res[$key])) == 0){unset($res[$key]);} } } @@ -143,21 +143,21 @@ $res = array_values($res); //Если шаблоны колонок заданы, но их не хватает - if ($tplX){ - if (($temp = count($res[0]) - count($tplX)) > 0){ + if ($colTpl !== false){ + if (($temp = count($res[0]) - count($colTpl)) > 0){ //Дозабьём недостающие последним - $tplX = array_merge($tplX, array_fill($temp - 1, $temp, $tplX[count($tplX) - 1])); + $colTpl = array_merge($colTpl, array_fill($temp - 1, $temp, $colTpl[count($colTpl) - 1])); } - $tplX = str_replace('null', '', $tplX); + $colTpl = str_replace('null', '', $colTpl); } $result = ''; - + //Если что-то есть (могло ничего не остаться после удаления пустых и/или получения по значениям) if (count($res) > 0){ //Если надо сортировать - if ($sortDir){ + if ($sortDir !== false){ //Если надо в случайном порядке - шафлим if ($sortDir == 'RAND'){ shuffle($res); @@ -165,149 +165,107 @@ }else if ($sortDir == 'REVERSE'){ $res = array_reverse($res); }else{ - if(!function_exists('ddMasHoarSort')){ - /** - * ddMasHoarSort - * @version 1.1 (2013-07-11) - * - * @desc Функция сортировки многомерного массива по методу Хоара (по нескольким полям одновременно). - * - * @param $arr {array} - Исходный массив. @required - * @param $key {array} - Массив ключей. @required - * @param $direct {1; -1} - Направление сортировки. @required - * @param $i {integer} - Счётчик (внутренняя переменная для рекурсии). По умолчанию: 0. - * - * @return {array} - */ - function ddMasHoarSort($arr, $key, $direct, $i = 0){ - //В качестве эталона получаем сортируемое значение (по первому условию сортировки) первого элемента - $tek = $arr[0][$key[$i]]; - $tekIsNumeric = is_numeric($tek); - - $masLeft = array(); - $masRight = array(); - $masCent = array(); - - //Перебираем массив - foreach ($arr as $val){ - //Если эталон и текущее значение — числа - if ($tekIsNumeric && is_numeric($val[$key[$i]])){ - //Получаем нужную циферку - $cmpRes = ($val[$key[$i]] == $tek) ? 0 : (($val[$key[$i]] > $tek) ? 1 : -1); - //Если они строки - }else{ - //Сравниваем текущее значение со значением эталонного - $cmpRes = strcmp($val[$key[$i]], $tek); - } - - //Если меньше эталона, отбрасываем в массив меньших - if ($cmpRes * $direct < 0){ - $masLeft[] = $val; - //Если больше - в массив больших - }else if ($cmpRes * $direct > 0){ - $masRight[] = $val; - //Если раво - в центральный - }else{ - $masCent[] = $val; - } - } - - //Массивы меньших и массивы больших прогоняем по тому же алгоритму (если в них что-то есть) - $masLeft = (count($masLeft) > 1) ? ddMasHoarSort($masLeft, $key, $direct, $i) : $masLeft; - $masRight = (count($masRight) > 1) ? ddMasHoarSort($masRight, $key, $direct, $i) : $masRight; - //Массив одинаковых прогоняем по следующему условию сортировки (если есть условие и есть что сортировать) - $masCent = ((count($masCent) > 1) && $key[$i + 1]) ? ddMasHoarSort($masCent, $key, $direct, $i + 1) : $masCent; - - //Склеиваем отсортированные меньшие, средние и большие - return array_merge($masLeft, $masCent, $masRight); - } - } - //Сортируем результаты - $sortDir = ($sortDir == 'ASC') ? 1 : -1; - $res = ddMasHoarSort($res, explode(',', $sortBy), $sortDir); + $res = ddTools::sort2dArray($res, explode(',', $sortBy), ($sortDir == 'ASC') ? 1 : -1); } } //Обрабатываем слишком большой индекс - if (!$res[$num]) $num = count($res) - 1; + if (!isset($res[$startRow])){$startRow = count($res) - 1;} //Если нужны все элементы - if ($count == 'all'){ - $res = array_slice($res, $num); + if ($totalRows == 'all'){ + $res = array_slice($res, $startRow); }else{ - $res = array_slice($res, $num, $count); + $res = array_slice($res, $startRow, $totalRows); } //Общее количество возвращаемых строк $resultTotal = count($res); //Плэйсхолдер с общим количеством - if (isset($totalPlaceholder) && strlen(trim($totalPlaceholder)) != ''){ - $modx->setPlaceholder($totalPlaceholder, $resultTotal); + if (isset($totalRowsToPlaceholder)){ + $modx->setPlaceholder($totalRowsToPlaceholder, $resultTotal); + } + + //Если нужно типографировать + if (isset($typography)){ + $typography = explode(',', $typography); + + //Придётся ещё раз перебрать результат + foreach ($res as $key => $val){ + //Перебираем колонки, заданные для типографирования + foreach ($typography as $v){ + //Если такая колонка существует, типографируем + if (isset($res[$key][$v])){ + $res[$key][$v] = $modx->runSnippet('ddTypograph', array('text' => $res[$key][$v])); + } + } + } } //Если вывод в массив - if ($format == 'array'){ + if ($outputFormat == 'array'){ $result = $res; }else{ $resTemp = array(); //Если вывод просто в формате html - if ($format == 'html'){ + if ($outputFormat == 'html'){ /*//Если вывод в формате изображения - if ($format == 'img'){ + if ($outputFormat == 'img'){ foreach ($res as $key => $val) $res[$key] = ''.$val['val0'].''; //Если вывод в формате ссылки - }else if ($format == 'link'){ + }else if ($outputFormat == 'link'){ foreach ($res as $key => $val) $res[$key] = ''.$val['val0'].''; //Если вывод по шаблону }else */ - if (isset($tplY)){ + if (isset($rowTpl)){ //Перебираем строки foreach ($res as $key => $val){ $resTemp[$key] = array(); + //Перебираем колонки foreach ($val as $k => $v){ //Если нужно удалять пустые значения if ($removeEmptyCols && !strlen($v)){ - $resTemp[$key]['val'.$k] = ''; + $resTemp[$key]['col'.$k] = ''; }else{ //Если есть шаблоны значений колонок - if ($tplX && strlen($tplX[$k])){ - $resTemp[$key]['val'.$k] = $modx->parseChunk($tplX[$k], array('val' => $v), '[+', '+]'); + if ($colTpl !== false && strlen($colTpl[$k]) > 0){ + $resTemp[$key]['col'.$k] = $modx->parseChunk($colTpl[$k], array('val' => $v), '[+', '+]'); }else{ - $resTemp[$key]['val'.$k] = $v; + $resTemp[$key]['col'.$k] = $v; } } } + //Запишем номер строки - $resTemp[$key]['row_number'] = $key + 1; + $resTemp[$key]['rowNumber'] = $key + 1; //И общее количество элементов $resTemp[$key]['total'] = $total; $resTemp[$key]['resultTotal'] = $resultTotal; - $resTemp[$key] = $modx->parseChunk($tplY, $resTemp[$key], '[+', '+]'); + $resTemp[$key] = $modx->parseChunk($rowTpl, $resTemp[$key], '[+', '+]'); } }else{ foreach ($res as $key => $val){ //Если есть шаблоны значений колонок - if ($tplX){ + if ($colTpl !== false){ foreach ($val as $k => $v){ if ($removeEmptyCols && !strlen($v)){ unset($val[$k]); - }else{ - if ($tplX && strlen($tplX[$k])) - $val[$k] = $modx->parseChunk($tplX[$k], array('val' => $v), '[+', '+]'); + }else if (strlen($colTpl[$k]) > 0){ + $val[$k] = $modx->parseChunk($colTpl[$k], array('val' => $v), '[+', '+]'); } } } - $resTemp[$key] = implode($glueX, $val); + $resTemp[$key] = implode($colGlue, $val); } } - $result = implode($glueY, $resTemp); + $result = implode($rowGlue, $resTemp); //Если вывод в формате JSON - }else if ($format == 'json'){ + }else if ($outputFormat == 'json'){ //Добавляем 'val' к названиям колонок /* foreach ($res as $key => $val){ $res[$key] = array(); @@ -318,13 +276,13 @@ function ddMasHoarSort($arr, $key, $direct, $i = 0){ $resTemp = $res; //Если нужно выводить только одну колонку - if ($colNum != 'all' && count($colNum) == 1){ + if ($columns != 'all' && count($columns) == 1){ $resTemp = array_map('implode', $resTemp); } //Если нужно получить какой-то конкретный элемент, а не все - if ($count == '1'){ - $result = json_encode($resTemp[$num]); + if ($totalRows == '1'){ + $result = json_encode($resTemp[$startRow]); }else{ $result = json_encode($resTemp); } @@ -334,21 +292,18 @@ function ddMasHoarSort($arr, $key, $direct, $i = 0){ } //Если оборачивающий шаблон задан (и вывод не в массив), парсим его - if (isset($tplWrap)){ - //Подключаем modx.ddTools - require_once $modx->config['base_path'].'assets/snippets/ddTools/modx.ddtools.class.php'; - + if (isset($outerTpl)){ $resTemp = array(); - //Элемент массива 'wrapper' должен находиться самым первым, иначе дополнительные переданные плэйсхолдеры в тексте не найдутся! - $resTemp['wrapper'] = $result; + //Элемент массива 'result' должен находиться самым первым, иначе дополнительные переданные плэйсхолдеры в тексте не найдутся! + $resTemp['result'] = $result; //Преобразуем результат в одномерный массив $res = ddTools::unfoldArray($res); //Добавляем 'row' и 'val' к ключам foreach ($res as $key => $val){ - $resTemp[preg_replace('/(\d)\.(\d)/', 'row$1.val$2', $key)] = $val; + $resTemp[preg_replace('/(\d)\.(\d)/', 'row$1.col$2', $key)] = $val; } //Если есть дополнительные данные @@ -358,13 +313,9 @@ function ddMasHoarSort($arr, $key, $direct, $i = 0){ $resTemp['total'] = $total; $resTemp['resultTotal'] = $resultTotal; - $result = $modx->parseChunk($tplWrap, $resTemp, '[+','+]'); - } - - //Если нужно типографировать - if ($typographing){ - $result = $modx->runSnippet('ddTypograph', array('text' => $result)); + $result = $modx->parseChunk($outerTpl, $resTemp, '[+','+]'); } + //Если нужно URL-кодировать строку if ($urlencode){ $result = rawurlencode($result); @@ -373,8 +324,8 @@ function ddMasHoarSort($arr, $key, $direct, $i = 0){ } //Если надо, выводим в плэйсхолдер - if ($resultToPlaceholder){ - $modx->setPlaceholder('ddGetMultipleField', $result); + if (isset($resultToPlaceholder)){ + $modx->setPlaceholder($resultToPlaceholder, $result); }else{ return $result; }