99.cache.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php return '/**
  2. * TaggerGetTags
  3. *
  4. * DESCRIPTION
  5. *
  6. * This Snippet allows you to list tags for resource(s), group(s) and all tags
  7. *
  8. * PROPERTIES:
  9. *
  10. * &resources string optional Comma separated list of resources for which will be listed Tags
  11. * &parents string optional Comma separated list of parents for which will be listed Tags
  12. * &groups string optional Comma separated list of Tagger Groups for which will be listed Tags
  13. * &rowTpl string optional Name of a chunk that will be used for each Tag. If no chunk is given, array with available placeholders will be rendered
  14. * &outTpl string optional Name of a chunk that will be used for wrapping all tags. If no chunk is given, tags will be rendered without a wrapper
  15. * &separator string optional String separator, that will be used for separating Tags
  16. * &limit int optional Limit number of returned tag Tags
  17. * &offset int optional Offset the output by this number of Tags
  18. * &totalPh string optional Placeholder to output the total number of Tags regardless of &limit and &offset
  19. * &target int optional An ID of a resource that will be used for generating URI for a Tag. If no ID is given, current Resource ID will be used
  20. * &showUnused int optional If 1 is set, Tags that are not assigned to any Resource will be included to the output as well
  21. * &showUnpublished int optional If 1 is set, Tags that are assigned only to unpublished Resources will be included to the output as well
  22. * &showDeleted int optional If 1 is set, Tags that are assigned only to deleted Resources will be included to the output as well
  23. * &linkCurrentTags int optional If 1 is set, Current Tags will be included in generated URL, default behavior is to generate links to a single tag
  24. * &linkOneTagPerGroup int optional If 1 is set, Only one tag will be placed to a group (in the URI tags from same group will swap places); Only available for linkCurrentTags=1; Default: 0
  25. * &contexts string optional If set, will display only tags for resources in given contexts. Contexts can be separated by a comma
  26. * &toPlaceholder string optional If set, output will return in placeholder with given name
  27. * &sort string optional Sort options in JSON. Example {"tag": "ASC"} or multiple sort options {"group_id": "ASC", "tag": "ASC"}
  28. * &friendlyURL int optional If set, will be used instead of friendly_urls system setting to generate URL
  29. * &linkTagScheme int|string optional Strategy to generate URLs, available values: -1, 0, 1, full, abs, http, https; Default: link_tag_scheme system setting
  30. *
  31. * USAGE:
  32. *
  33. * [[!TaggerGetTags? &showUnused=`1`]]
  34. *
  35. *
  36. * @package tagger
  37. */
  38. /** @var Tagger $tagger */
  39. $tagger = $modx->getService(\'tagger\',\'Tagger\',$modx->getOption(\'tagger.core_path\',null,$modx->getOption(\'core_path\').\'components/tagger/\').\'model/tagger/\',$scriptProperties);
  40. if (!($tagger instanceof Tagger)) return \'\';
  41. $resources = $modx->getOption(\'resources\', $scriptProperties, \'\');
  42. $parents = $modx->getOption(\'parents\', $scriptProperties, \'\');
  43. $groups = $modx->getOption(\'groups\', $scriptProperties, \'\');
  44. $target = (int) $modx->getOption(\'target\', $scriptProperties, $modx->resource->id, true);
  45. $showUnused = (int) $modx->getOption(\'showUnused\', $scriptProperties, \'0\');
  46. $showUnpublished = (int) $modx->getOption(\'showUnpublished\', $scriptProperties, \'0\');
  47. $showDeleted = (int) $modx->getOption(\'showDeleted\', $scriptProperties, \'0\');
  48. $linkCurrentTags = (int) $modx->getOption(\'linkCurrentTags\', $scriptProperties, \'0\');
  49. $linkOneTagPerGroup = (int) $modx->getOption(\'linkOneTagPerGroup\', $scriptProperties, \'0\');
  50. $contexts = $modx->getOption(\'contexts\', $scriptProperties, \'\');
  51. $translate = (int) $modx->getOption(\'translate\', $scriptProperties, \'0\');
  52. $defaultRowTpl = $modx->getOption(\'rowTpl\', $scriptProperties, \'\');
  53. $outTpl = $modx->getOption(\'outTpl\', $scriptProperties, \'\');
  54. $wrapIfEmpty = $modx->getOption(\'wrapIfEmpty\', $scriptProperties, 1);
  55. $separator = $modx->getOption(\'separator\', $scriptProperties, \'\');
  56. $limit = intval($modx->getOption(\'limit\', $scriptProperties, 0));
  57. $offset = intval($modx->getOption(\'offset\', $scriptProperties, 0));
  58. $totalPh = $modx->getOption(\'totalPh\', $scriptProperties, \'tags_total\');
  59. $weight = (int) $modx->getOption(\'weight\', $scriptProperties, \'0\');
  60. $friendlyURL = (int) $modx->getOption(\'friendlyURL\', $scriptProperties, $modx->getOption(\'friendly_urls\', null, 0));
  61. $linkTagScheme = $modx->getOption(\'linkTagScheme\', $scriptProperties, $modx->getOption(\'link_tag_scheme\', null, -1));
  62. $sort = $modx->getOption(\'sort\', $scriptProperties, \'{}\');
  63. $sort = $modx->fromJSON($sort);
  64. if ($sort === null || $sort == \'\' || count($sort) == 0) {
  65. $sort = array(
  66. \'tag\' => \'ASC\'
  67. );
  68. }
  69. $resources = $tagger->explodeAndClean($resources);
  70. $parents = $tagger->explodeAndClean($parents);
  71. $groups = $tagger->explodeAndClean($groups);
  72. $contexts = $tagger->explodeAndClean($contexts);
  73. $toPlaceholder = $modx->getOption(\'toPlaceholder\', $scriptProperties, \'\');
  74. $c = $modx->newQuery(\'TaggerTag\');
  75. $c->leftJoin(\'TaggerTagResource\', \'Resources\');
  76. $c->leftJoin(\'TaggerGroup\', \'Group\');
  77. $c->leftJoin(\'modResource\', \'Resource\', array(\'Resources.resource = Resource.id\'));
  78. if (!empty($parents)) {
  79. $c->where(array(
  80. \'Resource.parent:IN\' => $parents,
  81. ));
  82. }
  83. if (!empty($contexts)) {
  84. $c->where(array(
  85. \'Resource.context_key:IN\' => $contexts,
  86. ));
  87. }
  88. if ($showUnpublished == 0) {
  89. $c->where(array(
  90. \'Resource.published\' => 1,
  91. \'OR:Resource.published:IN\' => null,
  92. ));
  93. }
  94. if ($showDeleted == 0) {
  95. $c->where(array(
  96. \'Resource.deleted\' => 0,
  97. \'OR:Resource.deleted:IS\' => null,
  98. ));
  99. }
  100. if ($showUnused == 0) {
  101. $c->having(array(
  102. \'cnt > 0\',
  103. ));
  104. }
  105. if (!empty($resources)) {
  106. $c->where(array(
  107. \'Resources.resource:IN\' => $resources
  108. ));
  109. }
  110. if ($groups) {
  111. $c->where(array(
  112. \'Group.id:IN\' => $groups,
  113. \'OR:Group.name:IN\' => $groups,
  114. \'OR:Group.alias:IN\' => $groups,
  115. ));
  116. }
  117. $c->select($modx->getSelectColumns(\'TaggerTag\', \'TaggerTag\'));
  118. $c->select($modx->getSelectColumns(\'TaggerGroup\', \'Group\', \'group_\'));
  119. $c->select(array(\'cnt\' => \'COUNT(Resources.tag)\'));
  120. $c->groupby($modx->getSelectColumns(\'TaggerTag\', \'TaggerTag\') . \',\' . $modx->getSelectColumns(\'TaggerGroup\', \'Group\'));
  121. $c->prepare();
  122. $countQuery = new xPDOCriteria($modx, "SELECT COUNT(*) as total, MAX(cnt) as max_cnt FROM ({$c->toSQL(false)}) cq", $c->bindings, $c->cacheFlag);
  123. $stmt = $countQuery->prepare();
  124. if ($stmt && $stmt->execute()) {
  125. $fetchedData = $stmt->fetch(PDO::FETCH_ASSOC);
  126. $total = intval($fetchedData[\'total\']);
  127. $maxCnt = intval($fetchedData[\'max_cnt\']);
  128. } else {
  129. $total = 0;
  130. $maxCnt = 0;
  131. }
  132. $modx->setPlaceholder($totalPh, $total);
  133. foreach ($sort as $field => $dir) {
  134. $dir = (strtolower($dir) == \'asc\') ? \'asc\' : \'desc\';
  135. $c->sortby($field, $dir);
  136. }
  137. $c->limit($limit, $offset);
  138. $tags = $modx->getIterator(\'TaggerTag\', $c);
  139. $out = array();
  140. // prep for &tpl_N
  141. $keys = array_keys($scriptProperties);
  142. $nthTpls = array();
  143. foreach($keys as $key) {
  144. $keyBits = $tagger->explodeAndClean($key, \'_\');
  145. if (isset($keyBits[0]) && $keyBits[0] === \'tpl\') {
  146. if ($i = (int) $keyBits[1]) $nthTpls[$i] = $scriptProperties[$key];
  147. }
  148. }
  149. ksort($nthTpls);
  150. $idx = 1;
  151. $currentTags = $tagger->getCurrentTags();
  152. $currentTagsLink = array();
  153. if ($linkCurrentTags == 1) {
  154. foreach($currentTags as $currentTag) {
  155. $currentTagsLink[$currentTag[\'alias\']] = array_keys($currentTag[\'tags\']);
  156. }
  157. }
  158. foreach ($tags as $tag) {
  159. /** @var TaggerTag $tag */
  160. $phs = $tag->toArray();
  161. $group = $tag->Group;
  162. if (($linkOneTagPerGroup === 1) && $currentTagsLink[$group->alias]) {
  163. $linkData = $currentTagsLink;
  164. if (!in_array($tag->alias, $linkData[$group->alias])) {
  165. $linkData[$group->alias] = array($tag->alias);
  166. } else {
  167. $linkData[$group->alias] = array();
  168. }
  169. } else {
  170. $linkData = array_merge_recursive($currentTagsLink, array(
  171. $group->alias => array($tag->alias)
  172. ));
  173. }
  174. $linkData = array_filter(array_map(function($data) {
  175. return array_filter($data, function($value) use ($data) {
  176. return !(array_count_values($data)[$value] > 1);
  177. });
  178. }, $linkData));
  179. if ($friendlyURL == 1) {
  180. $linkPath = array_reduce(array_keys($linkData), function($carry, $item) use ($linkData) {
  181. return $carry . $item . \'/\' . implode(\'/\', array_unique($linkData[$item])) . \'/\';
  182. }, \'\');
  183. $uri = rtrim($modx->makeUrl($target, \'\', \'\', $linkTagScheme), \'/\') . \'/\' . $linkPath;
  184. } else {
  185. $linkPath = http_build_query(
  186. array_map(function($values) {
  187. return is_array($values) ? implode(\',\', array_unique($values)) : $values;
  188. }, $linkData)
  189. );
  190. $uri = $modx->makeUrl($target, \'\', $linkPath, $linkTagScheme);
  191. }
  192. $phs[\'uri\'] = $uri;
  193. $phs[\'idx\'] = $idx;
  194. $phs[\'target\'] = $target;
  195. $phs[\'max_cnt\'] = $maxCnt;
  196. if (isset($currentTags[$group->alias][\'tags\'][$tag->alias])) {
  197. $phs[\'active\'] = 1;
  198. } else {
  199. $phs[\'active\'] = 0;
  200. }
  201. if ($weight > 0) {
  202. $phs[\'weight\'] = intval(ceil($phs[\'cnt\'] / ($maxCnt / $weight)));
  203. }
  204. if ($translate == 1) {
  205. $groupNameTranslated = $modx->lexicon(\'tagger.custom.\' . $phs[\'group_alias\']);
  206. $groupDescriptionTranslated = $modx->lexicon(\'tagger.custom.\' . $phs[\'group_alias\'] . \'_desc\');
  207. $phs[\'group_name_translated\'] = ($groupNameTranslated == \'tagger.custom.\' . $phs[\'group_alias\']) ? $phs[\'group_name\'] : $groupNameTranslated;
  208. $phs[\'group_description_translated\'] = ($groupDescriptionTranslated == \'tagger.custom.\' . $phs[\'group_alias\'] . \'_desc\') ? $phs[\'group_description\'] : $groupDescriptionTranslated;
  209. }
  210. $rowTpl = $defaultRowTpl;
  211. $phs[\'sp\'] = $scriptProperties;
  212. if ($rowTpl == \'\') {
  213. $out[] = \'<pre>\' . print_r($phs, true) . \'</pre>\';
  214. } else {
  215. if (isset($nthTpls[$idx])) {
  216. $rowTpl = $nthTpls[$idx];
  217. } else {
  218. foreach ($nthTpls as $int => $tpl) {
  219. if ( ($idx % $int) === 0 ) $rowTpl = $tpl;
  220. }
  221. }
  222. $out[] = $tagger->getChunk($rowTpl, $phs);
  223. }
  224. $idx++;
  225. }
  226. $out = implode($separator, $out);
  227. if ($outTpl != \'\') {
  228. if (!empty($out) || $wrapIfEmpty) {
  229. $noActiveTags = (int)(count($currentTags) === 0);
  230. $out = $tagger->getChunk($outTpl, array(\'tags\' => $out, \'sp\' => $scriptProperties, \'noActiveTags\' => $noActiveTags));
  231. }
  232. }
  233. if (!empty($toPlaceholder)) {
  234. $modx->setPlaceholder($toPlaceholder, $out);
  235. return \'\';
  236. }
  237. return $out;
  238. return;
  239. ';