PageRenderTime 68ms CodeModel.GetById 34ms RepoModel.GetById 0ms app.codeStats 0ms

/assets/snippets/ditto/snippet.ditto.php

https://github.com/good-web-master/modx.evo.custom
PHP | 1083 lines | 212 code | 42 blank | 829 comment | 63 complexity | 2e737d94ea386ab2d5f5964ef7c4896e MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-1.0, GPL-2.0, MIT, BSD-3-Clause
  1. <?php
  2. if(!defined('MODX_BASE_PATH')) {die('What are you doing? Get out of here!');}
  3. /* Description:
  4. * Aggregates documents to create blogs, article/news
  5. * collections, and more,with full support for templating.
  6. *
  7. * Author:
  8. * Mark Kaplan for MODx CMF
  9. */
  10. //---Core Settings---------------------------------------------------- //
  11. $ditto_version = "2.1.0";
  12. // Ditto version being executed
  13. $ditto_base = isset($ditto_base) ? $modx->config['base_path'].$ditto_base : $modx->config['base_path']."assets/snippets/ditto/";
  14. /*
  15. Param: ditto_base
  16. Purpose:
  17. Location of Ditto files
  18. Options:
  19. Any valid folder location containing the Ditto source code with a trailing slash
  20. Default:
  21. [(base_path)]assets/snippets/ditto/
  22. */
  23. $dittoID = (!isset($id)) ? "" : $id."_";
  24. $GLOBALS["dittoID"] = $dittoID;
  25. /*
  26. Param: id
  27. Purpose:
  28. Unique ID for this Ditto instance for connection with other scripts (like Reflect) and unique URL parameters
  29. Options:
  30. Any combination of characters a-z, underscores, and numbers 0-9
  31. Note:
  32. This is case sensitive
  33. Default:
  34. "" - blank
  35. */
  36. $language = (isset($language))? $language : $modx->config['manager_language'];
  37. if (!file_exists($ditto_base."lang/".$language.".inc.php")) {
  38. $language ="english";
  39. }
  40. /*
  41. Param: language
  42. Purpose:
  43. language for defaults, debug, and error messages
  44. Options:
  45. Any language name with a corresponding file in the &ditto_base/lang folder
  46. Default:
  47. "english"
  48. */
  49. $format = (isset($format)) ? strtolower($format) : "html" ;
  50. /*
  51. Param: format
  52. Purpose:
  53. Output format to use
  54. Options:
  55. - "html"
  56. - "json"
  57. - "xml"
  58. - "atom"
  59. - "rss"
  60. Default:
  61. "html"
  62. */
  63. $config = (isset($config)) ? $config : "default";
  64. /*
  65. Param: config
  66. Purpose:
  67. Load a custom configuration
  68. Options:
  69. "default" - default blank config file
  70. CONFIG_NAME - Other configs installed in the configs folder or in any folder within the MODx base path via @FILE
  71. Default:
  72. "default"
  73. Related:
  74. - <extenders>
  75. */
  76. $debug = isset($debug)? $debug : 0;
  77. /*
  78. Param: debug
  79. Purpose:
  80. Output debugging information
  81. Options:
  82. 0 - off
  83. 1 - on
  84. Default:
  85. 0 - off
  86. Related:
  87. - <debug>
  88. */
  89. $phx = (isset($phx))? $phx : 0;
  90. /*
  91. Param: phx
  92. Purpose:
  93. Use PHx formatting
  94. Options:
  95. 0 - off
  96. 1 - on
  97. Default:
  98. 1 - on
  99. */
  100. $extenders = isset($extenders) ? explode(",",$extenders) : array();
  101. /*
  102. Param: extenders
  103. Purpose:
  104. Load an extender which adds functionality to Ditto
  105. Options:
  106. Any extender in the extenders folder or in any folder within the MODx base path via @FILE
  107. Default:
  108. [NULL]
  109. Related:
  110. - <config>
  111. */
  112. // Variable: extenders
  113. // Array that can be added to by configs or formats to load that extender
  114. $placeholders = array();
  115. // Variable: placeholders
  116. // Initialize custom placeholders array for configs or extenders to add to
  117. $filters = array("custom"=>array(),"parsed"=>array());
  118. // Variable: filters
  119. // Holds both the custom filters array for configs or extenders to add to
  120. // and the parsed filters array. To add to this array, use the following format
  121. // (code)
  122. // $filters["parsed"][] = array("name" => array("source"=>$source,"value"=>$value,"mode"=>$mode));
  123. // $filters["custom"][] = array("source","callback_function");
  124. $orderBy = array('parsed'=>array(),'custom'=>array(),'unparsed'=>$orderBy);
  125. // Variable: orderBy
  126. // An array that holds all criteria to sort the result set by.
  127. // Note that using a custom sort will disable all other sorting.
  128. // (code)
  129. // $orderBy["parsed"][] = array("sortBy","sortDir");
  130. // $orderBy["custom"][] = array("sortBy","callback_function");
  131. //---Includes-------------------------------------------------------- //
  132. $files = array (
  133. "base_language" => $ditto_base."lang/english.inc.php",
  134. "language" => $ditto_base."lang/$language.inc.php",
  135. "main_class" => $ditto_base."classes/ditto.class.inc.php",
  136. "template_class" => $ditto_base."classes/template.class.inc.php",
  137. "filter_class" => $ditto_base."classes/filter.class.inc.php",
  138. "format" => $ditto_base."formats/$format.format.inc.php",
  139. "config" => $ditto_base."configs/default.config.php",
  140. "user_config" => (substr($config, 0, 5) != "@FILE") ? $ditto_base."configs/$config.config.php" : $modx->config['base_path'].trim(substr($config, 5))
  141. );
  142. if ($phx == 1) {
  143. $files["prePHx_class"] = $ditto_base."classes/phx.pre.class.inc.php";
  144. }
  145. if (isset($randomize)) {
  146. $files["randomize_class"] = $ditto_base."classes/random.class.inc.php";
  147. }
  148. if ($debug == 1) {
  149. $files["modx_debug_class"] = $ditto_base."debug/modxDebugConsole.class.php";
  150. $files["debug_class"] = $ditto_base."classes/debug.class.inc.php";
  151. $files["debug_templates"] = $ditto_base."debug/debug.templates.php";
  152. }
  153. $files = array_unique($files);
  154. foreach ($files as $filename => $filevalue) {
  155. if (file_exists($filevalue) && strpos($filename,"class")) {
  156. include_once($filevalue);
  157. } else if (file_exists($filevalue)) {
  158. include($filevalue);
  159. } else if ($filename == "language") {
  160. $modx->logEvent(1, 3, "Language file does not exist Please check: " . $filevalue, "Ditto " . $ditto_version);
  161. return "Language file does not exist Please check: " . $filevalue;
  162. } else {
  163. $modx->logEvent(1, 3, $filevalue . " " . $_lang['file_does_not_exist'], "Ditto " . $ditto_version);
  164. return $filevalue . " " . $_lang['file_does_not_exist'];
  165. }
  166. }
  167. //---Initiate Class-------------------------------------------------- //
  168. if (class_exists('ditto')) {
  169. $ditto = new ditto($dittoID,$format,$_lang,$dbg_templates);
  170. // create a new Ditto instance in the specified format and language with the requested debug level
  171. } else {
  172. $modx->logEvent(1,3,$_lang['invalid_class'],"Ditto ".$ditto_version);
  173. return $_lang['invalid_class'];
  174. }
  175. //---Initiate Extenders---------------------------------------------- //
  176. if (isset($tagData)) {
  177. $extenders[] = "tagging";
  178. }
  179. if(count($extenders) > 0) {
  180. $extenders = array_unique($extenders);
  181. foreach ($extenders as $extender) {
  182. if(substr($extender, 0, 5) != "@FILE") {
  183. $extender_path = $ditto_base."extenders/".$extender.".extender.inc.php";
  184. } else {
  185. $extender_path = $modx->config['base_path'].trim(substr($extender, 5));
  186. }
  187. if (file_exists($extender_path)){
  188. include($extender_path);
  189. } else {
  190. $modx->logEvent(1, 3, $extender . " " . $_lang['extender_does_not_exist'], "Ditto ".$ditto_version);
  191. return $extender . " " . $_lang['extender_does_not_exist'];
  192. }
  193. }
  194. }
  195. //---Parameters------------------------------------------------------- /*
  196. if (isset($startID)) {$parents = $startID;}
  197. if (isset($summarize)) {$display = $summarize;}
  198. if (isset($limit)) {$queryLimit = $limit;}
  199. if (isset($sortBy) || isset($sortDir) || is_null($orderBy['unparsed'])) {
  200. $sortDir = isset($sortDir) ? strtoupper($sortDir) : 'DESC';
  201. $sortBy = isset($sortBy) ? $sortBy : "createdon";
  202. $orderBy['parsed'][]=array($sortBy,$sortDir);
  203. }
  204. // Allow backwards compatibility
  205. $idType = isset($documents) ? "documents" : "parents";
  206. // Variable: idType
  207. // type of IDs provided; can be either parents or documents
  208. $parents = isset($parents) ? $ditto->cleanIDs($parents) : $modx->documentIdentifier;
  209. /*
  210. Param: parents
  211. Purpose:
  212. IDs of containers for Ditto to retrieve their children to &depth depth
  213. Options:
  214. Any valid MODx document marked as a container
  215. Default:
  216. Current MODx Document
  217. Related:
  218. - <documents>
  219. - <depth>
  220. */
  221. $documents = isset($documents) ? $ditto->cleanIDs($documents) : false;
  222. /*
  223. Param: documents
  224. Purpose:
  225. IDs of documents for Ditto to retrieve
  226. Options:
  227. Any valid MODx document marked as a container
  228. Default:
  229. None
  230. Related:
  231. - <parents>
  232. */
  233. $IDs = ($idType == "parents") ? $parents : $documents;
  234. // Variable: IDs
  235. // Internal variable which holds the set of IDs for Ditto to fetch
  236. $depth = isset($depth) ? $depth : 1;
  237. /*
  238. Param: depth
  239. Purpose:
  240. Number of levels deep to retrieve documents
  241. Options:
  242. Any number greater than or equal to 1
  243. 0 - infinite depth
  244. Default:
  245. 1
  246. Related:
  247. - <seeThruUnpub>
  248. */
  249. $paginate = isset($paginate)? $paginate : 0;
  250. /*
  251. Param: paginate
  252. Purpose:
  253. Paginate the results set into pages of &display length.
  254. Use &total to limit the number of documents retreived.
  255. Options:
  256. 0 - off
  257. 1 - on
  258. Default:
  259. 0 - off
  260. Related:
  261. - <paginateAlwaysShowLinks>
  262. - <paginateSplitterCharacter>
  263. - <display>
  264. */
  265. $dateSource = isset($dateSource) ? $dateSource : "createdon";
  266. /*
  267. Param: dateSource
  268. Purpose:
  269. Source of the [+date+] placeholder
  270. Options:
  271. # - Any UNIX timestamp from MODx fields or TVs such as createdon, pub_date, or editedon
  272. Default:
  273. "createdon"
  274. Related:
  275. - <dateFormat>
  276. */
  277. $dateFormat = isset($dateFormat)? $dateFormat : $_lang["dateFormat"];
  278. /*
  279. Param: dateFormat
  280. Purpose:
  281. Format the [+date+] placeholder in human readable form
  282. Options:
  283. Any PHP valid strftime option
  284. Default:
  285. [LANG]
  286. Related:
  287. - <dateSource>
  288. */
  289. $display = isset($display) ? $display : "all";
  290. /*
  291. Param: display
  292. Purpose:
  293. Number of documents to display in the results
  294. Options:
  295. # - Any number
  296. "all" - All documents found
  297. Default:
  298. "all"
  299. Related:
  300. - <queryLimit>
  301. - <total>
  302. */
  303. $total = isset($total) ? $total : "all";
  304. /*
  305. Param: total
  306. Purpose:
  307. Number of documents to retrieve
  308. Options:
  309. # - Any number
  310. "all" - All documents found
  311. Default:
  312. "all" - All documents found
  313. Related:
  314. - <display>
  315. - <queryLimit>
  316. */
  317. $showPublishedOnly = isset($showPublishedOnly) ? $showPublishedOnly : 1;
  318. /*
  319. Param: showPublishedOnly
  320. Purpose:
  321. Show only published documents
  322. Options:
  323. 0 - show only unpublished documents
  324. 1 - show both published and unpublished documents
  325. Default:
  326. 1 - show both published and unpublished documents
  327. Related:
  328. - <seeThruUnpub>
  329. - <hideFolders>
  330. - <showPublishedOnly>
  331. - <where>
  332. */
  333. $showInMenuOnly = isset($showInMenuOnly) ? $showInMenuOnly : 0;
  334. /*
  335. Param: showInMenuOnly
  336. Purpose:
  337. Show only documents visible in the menu
  338. Options:
  339. 0 - show all documents
  340. 1 - show only documents with the show in menu flag checked
  341. Default:
  342. 0 - show all documents
  343. Related:
  344. - <seeThruUnpub>
  345. - <hideFolders>
  346. - <where>
  347. */
  348. $hideFolders = isset($hideFolders)? $hideFolders : 0;
  349. /*
  350. Param: hideFolders
  351. Purpose:
  352. Don't show folders in the returned results
  353. Options:
  354. 0 - keep folders
  355. 1 - remove folders
  356. Default:
  357. 0 - keep folders
  358. Related:
  359. - <seeThruUnpub>
  360. - <showInMenuOnly>
  361. - <where>
  362. */
  363. $hidePrivate = isset($hidePrivate)? $hidePrivate : 1;
  364. /*
  365. Param: hidePrivate
  366. Purpose:
  367. Don't show documents the guest or user does not have permission to see
  368. Options:
  369. 0 - show private documents
  370. 1 - hide private documents
  371. Default:
  372. 1 - hide private documents
  373. Related:
  374. - <seeThruUnpub>
  375. - <showInMenuOnly>
  376. - <where>
  377. */
  378. $seeThruUnpub = (isset($seeThruUnpub))? $seeThruUnpub : 1 ;
  379. /*
  380. Param: seeThruUnpub
  381. Purpose:
  382. See through unpublished folders to retrive their children
  383. Used when depth is greater than 1
  384. Options:
  385. 0 - off
  386. 1 - on
  387. Default:
  388. 0 - off
  389. Related:
  390. - <hideFolders>
  391. - <showInMenuOnly>
  392. - <where>
  393. */
  394. $queryLimit = (isset($queryLimit))? $queryLimit : 0;
  395. /*
  396. Param: queryLimit
  397. Purpose:
  398. Number of documents to retrieve from the database, same as MySQL LIMIT
  399. Options:
  400. # - Any number
  401. 0 - automatic
  402. Default:
  403. 0 - automatic
  404. Related:
  405. - <where>
  406. */
  407. $where = (isset($where))? $where : "";
  408. /*
  409. Param: where
  410. Purpose:
  411. Custom MySQL WHERE statement
  412. Options:
  413. A valid MySQL WHERE statement using only document object items (no TVs)
  414. Default:
  415. [NULL]
  416. Related:
  417. - <queryLimit>
  418. */
  419. $noResults = isset($noResults)? $ditto->getParam($noResults,"no_documents") : $_lang['no_documents'];
  420. /*
  421. Param: noResults
  422. Purpose:
  423. Text or chunk to display when there are no results
  424. Options:
  425. Any valid chunk name or text
  426. Default:
  427. [LANG]
  428. */
  429. $removeChunk = isset($removeChunk) ? explode(",",$removeChunk) : false;
  430. /*
  431. Param: removeChunk
  432. Purpose:
  433. Name of chunks to be stripped from content separated by commas
  434. - Commonly used to remove comments
  435. Options:
  436. Any valid chunkname that appears in the output
  437. Default:
  438. [NULL]
  439. */
  440. $hiddenFields = isset($hiddenFields) ? explode(",",$hiddenFields) : false;
  441. /*
  442. Param: hiddenFields
  443. Purpose:
  444. Allow Ditto to retrieve fields its template parser cannot handle such as nested placeholders and [*fields*]
  445. Options:
  446. Any valid MODx fieldnames or TVs comma separated
  447. Default:
  448. [NULL]
  449. */
  450. $offset = isset($start) ? $start : 0;
  451. $start = (isset($_GET[$dittoID.'start'])) ? intval($_GET[$dittoID.'start']) : 0;
  452. /*
  453. Param: start
  454. Purpose:
  455. Number of documents to skip in the results
  456. Options:
  457. Any number
  458. Default:
  459. 0
  460. */
  461. $globalFilterDelimiter = isset($globalFilterDelimiter) ? $globalFilterDelimiter : "|";
  462. /*
  463. Param: globalFilterDelimiter
  464. Purpose:
  465. Filter delimiter used to separate filters in the filter string
  466. Options:
  467. Any character not used in the filters
  468. Default:
  469. "|"
  470. Related:
  471. - <localFilterDelimiter>
  472. - <filter>
  473. - <parseFilters>
  474. */
  475. $localFilterDelimiter = isset($localFilterDelimiter) ? $localFilterDelimiter : ",";
  476. /*
  477. Param: localFilterDelimiter
  478. Purpose:
  479. Delimiter used to separate individual parameters within each filter string
  480. Options:
  481. Any character not used in the filter itself
  482. Default:
  483. ","
  484. Related:
  485. - <globalFilterDelimiter>
  486. - <filter>
  487. - <parseFilters>
  488. */
  489. $filters["custom"] = isset($cFilters) ? array_merge($filters["custom"],$cFilters) : $filters["custom"];
  490. $filters["parsed"] = isset($parsedFilters) ? array_merge($filters["parsed"],$parsedFilters) : $filters["parsed"];
  491. // handle 2.0.0 compatibility
  492. $filter = (isset($filter) || ($filters["custom"] != false) || ($filters["parsed"] != false)) ? $ditto->parseFilters($filter,$filters["custom"],$filters["parsed"],$globalFilterDelimiter,$localFilterDelimiter) : false;
  493. /*
  494. Param: filter
  495. Purpose:
  496. Removes items not meeting a critera. Thus, if pagetitle == joe then it will be removed.
  497. Use in the format field,criteria,mode with the comma being the local delimiter
  498. *Mode* *Meaning*
  499. 1 - !=
  500. 2 - ==
  501. 3 - <
  502. 4 - >
  503. 5 - <=
  504. 6 - >=
  505. 7 - Text not in field value
  506. 8 - Text in field value
  507. 9 - case insenstive version of #7
  508. 10 - case insenstive version of #8
  509. 11 - checks leading character of the field
  510. @EVAL:
  511. @EVAL in filters works the same as it does in MODx exect it can only be used
  512. with basic filtering, not custom filtering (tagging, etc). Make sure that
  513. you return the value you wish Ditto to filter by and that the code is valid PHP.
  514. Default:
  515. [NULL]
  516. Related:
  517. - <localFilterDelimiter>
  518. - <globalFilterDelimiter>
  519. - <parseFilters>
  520. */
  521. $keywords = (isset($keywords))? $keywords : 0;
  522. /*
  523. Param: keywords
  524. Purpose:
  525. Enable fetching of associated keywords for each document
  526. Can be used as [+keywords+] or as a tagData source
  527. Options:
  528. 0 - off
  529. 1 - on
  530. Default:
  531. 0 - off
  532. */
  533. $randomize = (isset($randomize))? $randomize : 0;
  534. /*
  535. Param: randomize
  536. Purpose:
  537. Randomize the order of the output
  538. Options:
  539. 0 - off
  540. 1 - on
  541. Any MODx field or TV for weighted random
  542. Default:
  543. 0 - off
  544. */
  545. $save = (isset($save))? $save : 0;
  546. /*
  547. Param: save
  548. Purpose:
  549. Saves the ditto object and results set to placeholders
  550. for use by other snippets
  551. Options:
  552. 0 - off; returns output
  553. 1 - remaining; returns output
  554. 2 - all;
  555. 3 - all; returns ph only
  556. Default:
  557. 0 - off; returns output
  558. */
  559. $templates = array(
  560. "default" => "@CODE".$_lang['default_template'],
  561. "base" => $tpl,
  562. "alt" => $tplAlt,
  563. "first" => $tplFirst,
  564. "last" => $tplLast,
  565. "current" => $tplCurrentDocument
  566. );
  567. /*
  568. Param: tpl
  569. Purpose:
  570. User defined chunk to format the documents
  571. Options:
  572. - Any valid chunk name
  573. - Code via @CODE
  574. - File via @FILE
  575. Default:
  576. [LANG]
  577. */
  578. /*
  579. Param: tplAlt
  580. Purpose:
  581. User defined chunk to format every other document
  582. Options:
  583. - Any valid chunk name
  584. - Code via @CODE
  585. - File via @FILE
  586. Default:
  587. &tpl
  588. */
  589. /*
  590. Param: tplFirst
  591. Purpose:
  592. User defined chunk to format the first document
  593. Options:
  594. - Any valid chunk name
  595. - Code via @CODE
  596. - File via @FILE
  597. Default:
  598. &tpl
  599. */
  600. /*
  601. Param: tplLast
  602. Purpose:
  603. User defined chunk to format the last document
  604. Options:
  605. - Any valid chunk name
  606. - Code via @CODE
  607. - File via @FILE
  608. Default:
  609. &tpl
  610. */
  611. /*
  612. Param: tplCurrentDocument
  613. Purpose:
  614. User defined chunk to format the current document
  615. Options:
  616. - Any valid chunk name
  617. - Code via @CODE
  618. - File via @FILE
  619. Default:
  620. &tpl
  621. */
  622. $orderBy = $ditto->parseOrderBy($orderBy,$randomize);
  623. /*
  624. Param: orderBy
  625. Purpose:
  626. Sort the result set
  627. Options:
  628. Any valid MySQL style orderBy statement
  629. Default:
  630. createdon DESC
  631. */
  632. //-------------------------------------------------------------------- */
  633. $templates = $ditto->template->process($templates);
  634. // parse the templates for TV's and store them for later use
  635. $ditto->setDisplayFields($ditto->template->fields,$hiddenFields);
  636. // parse hidden fields
  637. $ditto->parseFields($placeholders,$seeThruUnpub,$dateSource,$randomize);
  638. // parse the fields into the field array
  639. $documentIDs = $ditto->determineIDs($IDs, $idType, $ditto->fields["backend"]["tv"], $orderBy, $depth, $showPublishedOnly, $seeThruUnpub, $hideFolders, $hidePrivate, $showInMenuOnly, $where, $keywords, $dateSource, $queryLimit, $display, $filter,$paginate, $randomize);
  640. // retrieves a list of document IDs that meet the criteria and populates the $resources array with them
  641. $count = count($documentIDs);
  642. // count the number of documents to be retrieved
  643. $count = $count-$offset;
  644. // handle the offset
  645. if ($count > 0) {
  646. // if documents are returned continue with execution
  647. $total = ($total == "all") ? $count : min($total,$count);
  648. // set total equal to count if all documents are to be included
  649. $display = ($display == "all") ? min($count,$total) : min($display,$total);
  650. // allow show to use all option
  651. $stop = ($save != "1") ? min($total-$start,$display) : min($count,$total);
  652. // set initial stop count
  653. if($paginate == 1) {
  654. $paginateAlwaysShowLinks = isset($paginateAlwaysShowLinks)? $paginateAlwaysShowLinks : 0;
  655. /*
  656. Param: paginateAlwaysShowLinks
  657. Purpose:
  658. Determine whether or not to always show previous next links
  659. Options:
  660. 0 - off
  661. 1 - on
  662. Default:
  663. 0 - off
  664. Related:
  665. - <paginate>
  666. - <paginateSplitterCharacter>
  667. */
  668. $paginateSplitterCharacter = isset($paginateSplitterCharacter)? $paginateSplitterCharacter : $_lang['button_splitter'];
  669. /*
  670. Param: paginateSplitterCharacter
  671. Purpose:
  672. Splitter to use if always show is disabled
  673. Options:
  674. Any valid character
  675. Default:
  676. [LANG]
  677. Related:
  678. - <paginate>
  679. - <paginateSplitterCharacter>
  680. */
  681. $tplPaginatePrevious = isset($tplPaginatePrevious)? $ditto->template->fetch($tplPaginatePrevious) : "<a href='[+url+]' class='ditto_previous_link'>[+lang:previous+]</a>";
  682. /*
  683. Param: tplPaginatePrevious
  684. Purpose:
  685. Template for the previous link
  686. Options:
  687. - Any valid chunk name
  688. - Code via @CODE
  689. - File via @FILE
  690. Placeholders:
  691. url - URL for the previous link
  692. lang:previous - value of 'prev' from the language file
  693. Related:
  694. - <tplPaginateNext>
  695. - <paginateSplitterCharacter>
  696. */
  697. $tplPaginateNext = isset($tplPaginateNext)? $ditto->template->fetch($tplPaginateNext) : "<a href='[+url+]' class='ditto_next_link'>[+lang:next+]</a>";
  698. /*
  699. Param: tplPaginateNext
  700. Purpose:
  701. Template for the next link
  702. Options:
  703. - Any valid chunk name
  704. - Code via @CODE
  705. - File via @FILE
  706. Placeholders:
  707. url - URL for the next link
  708. lang:next - value of 'next' from the language file
  709. Related:
  710. - <tplPaginatePrevious>
  711. - <paginateSplitterCharacter>
  712. */
  713. $tplPaginateNextOff = isset($tplPaginateNextOff)? $ditto->template->fetch($tplPaginateNextOff) : "<span class='ditto_next_off ditto_off'>[+lang:next+]</span>";
  714. /*
  715. Param: tplPaginateNextOff
  716. Purpose:
  717. Template for the inside of the next link
  718. Options:
  719. - Any valid chunk name
  720. - Code via @CODE
  721. - File via @FILE
  722. Placeholders:
  723. lang:next - value of 'next' from the language file
  724. Related:
  725. - <tplPaginatePrevious>
  726. - <paginateSplitterCharacter>
  727. */
  728. $tplPaginatePreviousOff = isset($tplPaginatePreviousOff)? $ditto->template->fetch($tplPaginatePreviousOff) : "<span class='ditto_previous_off ditto_off'>[+lang:previous+]</span>";
  729. /*
  730. Param: tplPaginatePreviousOff
  731. Purpose:
  732. Template for the previous link when it is off
  733. Options:
  734. - Any valid chunk name
  735. - Code via @CODE
  736. - File via @FILE
  737. Placeholders:
  738. lang:previous - value of 'prev' from the language file
  739. Related:
  740. - <tplPaginatePrevious>
  741. - <paginateSplitterCharacter>
  742. */
  743. $tplPaginatePage = isset($tplPaginatePage)? $ditto->template->fetch($tplPaginatePage) : "<a class='ditto_page' href='[+url+]'>[+page+]</a>";
  744. /*
  745. Param: tplPaginatePage
  746. Purpose:
  747. Template for the page link
  748. Options:
  749. - Any valid chunk name
  750. - Code via @CODE
  751. - File via @FILE
  752. Placeholders:
  753. url - url for the page
  754. page - number of the page
  755. Related:
  756. - <tplPaginatePrevious>
  757. - <paginateSplitterCharacter>
  758. */
  759. $tplPaginateCurrentPage = isset($tplPaginateCurrentPage)? $ditto->template->fetch($tplPaginateCurrentPage) : "<span class='ditto_currentpage'>[+page+]</span>";
  760. /*
  761. Param: tplPaginateCurrentPage
  762. Purpose:
  763. Template for the current page link
  764. Options:
  765. - Any valid chunk name
  766. - Code via @CODE
  767. - File via @FILE
  768. Placeholders:
  769. page - number of the page
  770. Related:
  771. - <tplPaginatePrevious>
  772. - <paginateSplitterCharacter>
  773. */
  774. $ditto->paginate($start, $stop, $total, $display, $tplPaginateNext, $tplPaginatePrevious, $tplPaginateNextOff, $tplPaginatePreviousOff, $tplPaginatePage, $tplPaginateCurrentPage, $paginateAlwaysShowLinks, $paginateSplitterCharacter);
  775. // generate the pagination placeholders
  776. }
  777. $dbFields = $ditto->fields["display"]["db"];
  778. // get the database fields
  779. $TVs = $ditto->fields["display"]["tv"];
  780. // get the TVs
  781. switch($orderBy['parsed'][0][1]) {
  782. case "DESC":
  783. $stop = ($ditto->prefetch === false) ? $stop + $start + $offset : $stop + $offset;
  784. $start += $offset;
  785. break;
  786. case "ASC":
  787. $start += $offset;
  788. $stop += $start;
  789. break;
  790. }
  791. if ($ditto->prefetch !== false) {
  792. $documentIDs = array_slice($documentIDs,$start,$stop);
  793. // set the document IDs equal to the trimmed array
  794. $dbFields = array_diff($dbFields,$ditto->prefetch["fields"]["db"]);
  795. // calculate the difference between the database fields and those already prefetched
  796. $dbFields[] = "id";
  797. // append id to the db fields array
  798. $TVs = array_diff($TVs,$ditto->prefetch["fields"]["tv"]);
  799. // calculate the difference between the tv fields and those already prefetched
  800. $start = 0;
  801. $stop = min($display,($queryLimit != 0) ? $queryLimit : $display,count($documentIDs));
  802. } else {
  803. $queryLimit = ($queryLimit == 0) ? "" : $queryLimit;
  804. }
  805. $resource = $ditto->getDocuments($documentIDs, $dbFields, $TVs, $orderBy, $showPublishedOnly, 0, $hidePrivate, $where, $queryLimit, $keywords, $randomize, $dateSource);
  806. // retrieves documents
  807. $output = $header;
  808. // initialize the output variable and send the header
  809. if ($resource) {
  810. if ($randomize != "0" && $randomize != "1") {
  811. $resource = $ditto->weightedRandom($resource,$randomize,$stop);
  812. // randomize the documents
  813. }
  814. $resource = array_values($resource);
  815. for ($x=$start;$x<$stop;$x++) {
  816. $template = $ditto->template->determine($templates,$x,0,$stop,$resource[$x]["id"]);
  817. // choose the template to use and set the code of that template to the template variable
  818. $renderedOutput = $ditto->render($resource[$x], $template, $removeChunk, $dateSource, $dateFormat, $placeholders,$phx,abs($start-$x));
  819. // render the output using the correct template, in the correct format and language
  820. $modx->setPlaceholder($dittoID."item[".abs($start-$x)."]",$renderedOutput);
  821. /*
  822. Placeholder: item[x]
  823. Content:
  824. Individual items rendered output
  825. */
  826. $output .= $renderedOutput;
  827. // send the rendered output to the buffer
  828. }
  829. } else {
  830. $output .= $ditto->noResults($noResults,$paginate);
  831. // if no documents are found return a no documents found string
  832. }
  833. $output .= $footer;
  834. // send the footer
  835. // ---------------------------------------------------
  836. // Save Object
  837. // ---------------------------------------------------
  838. if($save) {
  839. $modx->setPlaceholder($dittoID."ditto_object", $ditto);
  840. $modx->setPlaceholder($dittoID."ditto_resource", ($save == "1") ? array_slice($resource,$display) : $resource);
  841. }
  842. } else {
  843. $output = $header.$ditto->noResults($noResults,$paginate).$footer;
  844. }
  845. // ---------------------------------------------------
  846. // Handle Debugging
  847. // ---------------------------------------------------
  848. if ($debug == 1) {
  849. $ditto_params =& $modx->event_params;
  850. if (!isset($_GET["ditto_".$dittoID."debug"])) {
  851. $_SESSION["ditto_debug_$dittoID"] = $ditto->debug->render_popup($ditto, $ditto_base, $ditto_version, $ditto_params, $documentIDs, array("db"=>$dbFields,"tv"=>$TVs), $display, $templates, $orderBy, $start, $stop, $total,$filter,$resource);
  852. }
  853. if (isset($_GET["ditto_".$dittoID."debug"])) {
  854. switch ($_GET["ditto_".$dittoID."debug"]) {
  855. case "open" :
  856. exit($_SESSION["ditto_debug_$dittoID"]);
  857. break;
  858. case "save" :
  859. $ditto->debug->save($_SESSION["ditto_debug_$dittoID"],"ditto".strtolower($ditto_version)."_debug_doc".$modx->documentIdentifier.".html");
  860. break;
  861. }
  862. } else {
  863. $output = $ditto->debug->render_link($dittoID,$ditto_base).$output;
  864. }
  865. }
  866. return ($save != 3) ? $output : "";
  867. ?>