getService('tagger','Tagger',$modx->getOption('tagger.core_path',null,$modx->getOption('core_path').'components/tagger/').'model/tagger/',$scriptProperties); if (!($tagger instanceof Tagger)) return ''; $resources = $modx->getOption('resources', $scriptProperties, ''); $parents = $modx->getOption('parents', $scriptProperties, ''); $groups = $modx->getOption('groups', $scriptProperties, ''); $target = (int) $modx->getOption('target', $scriptProperties, $modx->resource->id, true); $showUnused = (int) $modx->getOption('showUnused', $scriptProperties, '0'); $showUnpublished = (int) $modx->getOption('showUnpublished', $scriptProperties, '0'); $showDeleted = (int) $modx->getOption('showDeleted', $scriptProperties, '0'); $linkCurrentTags = (int) $modx->getOption('linkCurrentTags', $scriptProperties, '0'); $linkOneTagPerGroup = (int) $modx->getOption('linkOneTagPerGroup', $scriptProperties, '0'); $contexts = $modx->getOption('contexts', $scriptProperties, ''); $translate = (int) $modx->getOption('translate', $scriptProperties, '0'); $defaultRowTpl = $modx->getOption('rowTpl', $scriptProperties, ''); $outTpl = $modx->getOption('outTpl', $scriptProperties, ''); $wrapIfEmpty = $modx->getOption('wrapIfEmpty', $scriptProperties, 1); $separator = $modx->getOption('separator', $scriptProperties, ''); $limit = intval($modx->getOption('limit', $scriptProperties, 0)); $offset = intval($modx->getOption('offset', $scriptProperties, 0)); $totalPh = $modx->getOption('totalPh', $scriptProperties, 'tags_total'); $weight = (int) $modx->getOption('weight', $scriptProperties, '0'); $friendlyURL = (int) $modx->getOption('friendlyURL', $scriptProperties, $modx->getOption('friendly_urls', null, 0)); $linkTagScheme = $modx->getOption('linkTagScheme', $scriptProperties, $modx->getOption('link_tag_scheme', null, -1)); $sort = $modx->getOption('sort', $scriptProperties, '{}'); $sort = $modx->fromJSON($sort); if ($sort === null || $sort == '' || count($sort) == 0) { $sort = array( 'tag' => 'ASC' ); } $resources = $tagger->explodeAndClean($resources); $parents = $tagger->explodeAndClean($parents); $groups = $tagger->explodeAndClean($groups); $contexts = $tagger->explodeAndClean($contexts); $toPlaceholder = $modx->getOption('toPlaceholder', $scriptProperties, ''); $c = $modx->newQuery('TaggerTag'); $c->leftJoin('TaggerTagResource', 'Resources'); $c->leftJoin('TaggerGroup', 'Group'); $c->leftJoin('modResource', 'Resource', array('Resources.resource = Resource.id')); if (!empty($parents)) { $c->where(array( 'Resource.parent:IN' => $parents, )); } if (!empty($contexts)) { $c->where(array( 'Resource.context_key:IN' => $contexts, )); } if ($showUnpublished == 0) { $c->where(array( 'Resource.published' => 1, 'OR:Resource.published:IN' => null, )); } if ($showDeleted == 0) { $c->where(array( 'Resource.deleted' => 0, 'OR:Resource.deleted:IS' => null, )); } if ($showUnused == 0) { $c->having(array( 'cnt > 0', )); } if (!empty($resources)) { $c->where(array( 'Resources.resource:IN' => $resources )); } if ($groups) { $c->where(array( 'Group.id:IN' => $groups, 'OR:Group.name:IN' => $groups, 'OR:Group.alias:IN' => $groups, )); } $c->select($modx->getSelectColumns('TaggerTag', 'TaggerTag')); $c->select($modx->getSelectColumns('TaggerGroup', 'Group', 'group_')); $c->select(array('cnt' => 'COUNT(Resources.tag)')); $c->groupby($modx->getSelectColumns('TaggerTag', 'TaggerTag') . ',' . $modx->getSelectColumns('TaggerGroup', 'Group')); $c->prepare(); $countQuery = new xPDOCriteria($modx, "SELECT COUNT(*) as total, MAX(cnt) as max_cnt FROM ({$c->toSQL(false)}) cq", $c->bindings, $c->cacheFlag); $stmt = $countQuery->prepare(); if ($stmt && $stmt->execute()) { $fetchedData = $stmt->fetch(PDO::FETCH_ASSOC); $total = intval($fetchedData['total']); $maxCnt = intval($fetchedData['max_cnt']); } else { $total = 0; $maxCnt = 0; } $modx->setPlaceholder($totalPh, $total); foreach ($sort as $field => $dir) { $dir = (strtolower($dir) == 'asc') ? 'asc' : 'desc'; $c->sortby($field, $dir); } $c->limit($limit, $offset); $tags = $modx->getIterator('TaggerTag', $c); $out = array(); // prep for &tpl_N $keys = array_keys($scriptProperties); $nthTpls = array(); foreach($keys as $key) { $keyBits = $tagger->explodeAndClean($key, '_'); if (isset($keyBits[0]) && $keyBits[0] === 'tpl') { if ($i = (int) $keyBits[1]) $nthTpls[$i] = $scriptProperties[$key]; } } ksort($nthTpls); $idx = 1; $currentTags = $tagger->getCurrentTags(); $currentTagsLink = array(); if ($linkCurrentTags == 1) { foreach($currentTags as $currentTag) { $currentTagsLink[$currentTag['alias']] = array_keys($currentTag['tags']); } } foreach ($tags as $tag) { /** @var TaggerTag $tag */ $phs = $tag->toArray(); $group = $tag->Group; if (($linkOneTagPerGroup === 1) && $currentTagsLink[$group->alias]) { $linkData = $currentTagsLink; if (!in_array($tag->alias, $linkData[$group->alias])) { $linkData[$group->alias] = array($tag->alias); } else { $linkData[$group->alias] = array(); } } else { $linkData = array_merge_recursive($currentTagsLink, array( $group->alias => array($tag->alias) )); } $linkData = array_filter(array_map(function($data) { return array_filter($data, function($value) use ($data) { return !(array_count_values($data)[$value] > 1); }); }, $linkData)); if ($friendlyURL == 1) { $linkPath = array_reduce(array_keys($linkData), function($carry, $item) use ($linkData) { return $carry . $item . '/' . implode('/', array_unique($linkData[$item])) . '/'; }, ''); $uri = rtrim($modx->makeUrl($target, '', '', $linkTagScheme), '/') . '/' . $linkPath; } else { $linkPath = http_build_query( array_map(function($values) { return is_array($values) ? implode(',', array_unique($values)) : $values; }, $linkData) ); $uri = $modx->makeUrl($target, '', $linkPath, $linkTagScheme); } $phs['uri'] = $uri; $phs['idx'] = $idx; $phs['target'] = $target; $phs['max_cnt'] = $maxCnt; if (isset($currentTags[$group->alias]['tags'][$tag->alias])) { $phs['active'] = 1; } else { $phs['active'] = 0; } if ($weight > 0) { $phs['weight'] = intval(ceil($phs['cnt'] / ($maxCnt / $weight))); } if ($translate == 1) { $groupNameTranslated = $modx->lexicon('tagger.custom.' . $phs['group_alias']); $groupDescriptionTranslated = $modx->lexicon('tagger.custom.' . $phs['group_alias'] . '_desc'); $phs['group_name_translated'] = ($groupNameTranslated == 'tagger.custom.' . $phs['group_alias']) ? $phs['group_name'] : $groupNameTranslated; $phs['group_description_translated'] = ($groupDescriptionTranslated == 'tagger.custom.' . $phs['group_alias'] . '_desc') ? $phs['group_description'] : $groupDescriptionTranslated; } $rowTpl = $defaultRowTpl; $phs['sp'] = $scriptProperties; if ($rowTpl == '') { $out[] = '
' . print_r($phs, true) . '
'; } else { if (isset($nthTpls[$idx])) { $rowTpl = $nthTpls[$idx]; } else { foreach ($nthTpls as $int => $tpl) { if ( ($idx % $int) === 0 ) $rowTpl = $tpl; } } $out[] = $tagger->getChunk($rowTpl, $phs); } $idx++; } $out = implode($separator, $out); if ($outTpl != '') { if (!empty($out) || $wrapIfEmpty) { $noActiveTags = (int)(count($currentTags) === 0); $out = $tagger->getChunk($outTpl, array('tags' => $out, 'sp' => $scriptProperties, 'noActiveTags' => $noActiveTags)); } } if (!empty($toPlaceholder)) { $modx->setPlaceholder($toPlaceholder, $out); return ''; } return $out; return;