Advertisement
Guest User

Untitled

a guest
Dec 4th, 2016
105
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.36 KB | None | 0 0
  1. <?php
  2. use modmore\Alpacka\Snippet;
  3. use modmore\Alpacka\Properties\SimpleProperty;
  4. use modmore\Alpacka\Properties\BooleanProperty;
  5. use modmore\Alpacka\Properties\EnumProperty;
  6.  
  7. /**
  8. * Class GetImagesSnippet
  9. *
  10. * Gets a collection of images and videos.
  11. *
  12. * @property moreGallery $service
  13. */
  14. class GetImages extends Snippet {
  15. protected $resourceFields = array(
  16. 'id', 'alias', 'uri', 'uri_override',
  17. 'pagetitle', 'longtitle', 'menutitle',
  18. 'description', 'introtext', 'link_attributes',
  19. 'parent', 'context_key', 'template', 'class_key', 'content_type',
  20. 'published', 'pub_date', 'unpub_date', 'publishedon', 'publishedby',
  21. 'isfolder', 'richtext', 'searchable', 'cacheable', 'deleted', 'hide_children_in_tree', 'show_in_tree',
  22. 'createdby', 'createdon', 'editedby', 'editedon', 'deletedby', 'deletedon',
  23. );
  24. protected $cacheOptions = array(
  25. xPDO::OPT_CACHE_KEY => 'moregallery'
  26. );
  27.  
  28. /** @var modResource[] */
  29. protected $_resources = array();
  30. /** @var array[] */
  31. protected $_resourceData = array();
  32. protected $chunkHash = '';
  33. protected $_idx = 0;
  34. protected $singleImageParam = '';
  35.  
  36. /**
  37. * The available properties for this snippet.
  38. *
  39. * @return array
  40. */
  41. public function getPropertiesDefinition()
  42. {
  43. return array(
  44. 'cache' => new BooleanProperty(true),
  45. 'resource' => new SimpleProperty(0),
  46. 'activeOnly' => new BooleanProperty(true),
  47. 'sortBy' => new SimpleProperty('sortorder'),
  48. 'sortDir' => new EnumProperty('ASC', array('ASC', 'DESC')),
  49. 'where' => new SimpleProperty(),
  50.  
  51. 'tags' => new SimpleProperty(),
  52. 'tagsFromUrl' => new SimpleProperty(),
  53. 'tagSeparator' => new SimpleProperty("\n"),
  54.  
  55. 'getTags' => new BooleanProperty(true),
  56. 'getResourceContent' => new BooleanProperty(false),
  57. 'getResourceProperties' => new BooleanProperty(false),
  58. 'getResourceFields' => new BooleanProperty(false),
  59. 'getResourceTVs' => new SimpleProperty(),
  60.  
  61. 'tagTpl' => new SimpleProperty('mgtag'),
  62. 'imageTpl' => new SimpleProperty('mgimage'),
  63. 'youtubeTpl' => new SimpleProperty('mgYoutube'),
  64. 'vimeoTpl' => new SimpleProperty('mgVimeo'),
  65. 'imageSeparator' => new SimpleProperty("\n"),
  66. 'singleImageTpl' => new SimpleProperty('mgimagesingle'),
  67. 'singleYoutubeTpl' => new SimpleProperty('mgYoutubeSingle'),
  68. 'singleVimeoTpl' => new SimpleProperty('mgVimeoSingle'),
  69. 'singleImageEnabled' => new BooleanProperty(true),
  70. 'singleImageParam' => new SimpleProperty(),
  71. 'singleImageResource' => new SimpleProperty(0),
  72. 'wrapperTpl' => new SimpleProperty(),
  73. 'wrapperIfEmpty' => new BooleanProperty(true),
  74. 'toPlaceholder' => new SimpleProperty(),
  75.  
  76. 'limit' => new SimpleProperty(0),
  77. 'offset' => new SimpleProperty(0),
  78. 'totalVar' => new SimpleProperty('total'),
  79.  
  80. 'scheme' => new SimpleProperty($this->service->getOption('link_tag_scheme')),
  81.  
  82. 'debug' => new BooleanProperty(false),
  83. 'timing' => new BooleanProperty(false),
  84. );
  85. }
  86.  
  87. public function initialize()
  88. {
  89. $resourceId = $this->getProperty('resource');
  90. if ($resourceId < 1 && $this->modx->resource) {
  91. $resourceId = $this->modx->resource->get('id');
  92. $this->setProperty('resource', $resourceId);
  93. }
  94.  
  95. // Get the singleImageParam property and default it to the setting if empty
  96. $singleImageParam = $this->getProperty('singleImageParam');
  97. if (empty($singleImageParam)) {
  98. $singleImageParam = $this->service->getOption('moregallery.single_image_url_param');
  99. }
  100. $this->singleImageParam = $singleImageParam;
  101.  
  102. $context = 'web';
  103. if ($resourceId > 0) {
  104. if ($this->modx->resource && $this->modx->resource->get('id') == $resourceId) {
  105. $context = $this->modx->resource->get('context_key');
  106. }
  107. else {
  108. $resource = $this->modx->getObject('modResource', (int)$resourceId);
  109. if ($resource instanceof modResource) {
  110. $context = $resource->get('context_key');
  111. }
  112. }
  113. }
  114. $this->debug('Setting working context to ' . $context);
  115. $this->service->setWorkingContext($context);
  116. }
  117.  
  118. /**
  119. * @return string
  120. */
  121. public function process()
  122. {
  123. $this->initialize();
  124.  
  125. if (array_key_exists($this->singleImageParam, $_REQUEST)) {
  126. $this->debug('URL parameter "' . $this->singleImageParam . '" exists on $_REQUEST, so showing single image.');
  127. return $this->getSingleImage((int)$_REQUEST[$this->singleImageParam]);
  128. }
  129. $this->debug('No URL parameter ' . $this->singleImageParam . ' exists on $_REQUEST, so showing image collection.');
  130. return $this->getImageCollection();
  131. }
  132.  
  133. /**
  134. * Returns image $imageId, from cache if possible.
  135. *
  136. * @param $imageId
  137. * @return string
  138. * @throws \modmore\Alpacka\Exceptions\InvalidPropertyException
  139. */
  140. public function getSingleImage($imageId)
  141. {
  142. // Try to load from cache first
  143. $cacheKey = 'single-image/' . $this->getProperty('resource') . '/' . $imageId . '_' . $this->getPropertyHash() . '_' . $this->getChunkHash();
  144. if ($this->getProperty('cache')) {
  145. $cached = $this->modx->cacheManager->get($cacheKey, $this->cacheOptions);
  146. if (is_array($cached)) {
  147. $this->debug('Loaded single image ' . $imageId . ' from cache using cacheKey ' . $cacheKey);
  148. return $this->finish($cached['formatted']);
  149. }
  150. }
  151.  
  152. // No cache available, so fetch it from the database.
  153. $filter = array(
  154. 'id' => $imageId,
  155. 'resource' => $this->getProperty('resource'),
  156. );
  157. if ($this->getProperty('activeOnly')) {
  158. $filter['active'] = true;
  159. }
  160. /** @var mgImage $image */
  161. $image = $this->modx->getObject('mgImage', $filter);
  162.  
  163. // If the image can't be found, we send the user to the error page.
  164. // @todo Consider redirecting the user to the "parent" page (i.e. current page without &iid url param) instead?
  165. if (!$image) {
  166. $this->debug('Image not found with filter' . print_r($filter, true));
  167. $this->modx->sendErrorPage();
  168. }
  169.  
  170. $this->debug('Image loaded, now loading all placeholders.');
  171. // Turn the image into placeholders, including previous and next images.
  172. $phs = $this->getImagePlaceholders($image, true);
  173.  
  174. // Format it
  175. $tpl = $this->determineSingleTpl($phs);
  176. $this->debug('Formatting image with chunk ' . $tpl);
  177. $formatted = $this->service->getChunk($tpl, $phs);
  178.  
  179. // If cache is enabled, write the data to the proper cache file.
  180. if ($this->getProperty('cache')) {
  181. $cached = array(
  182. 'placeholders' => $phs,
  183. 'formatted' => $formatted,
  184. );
  185. $this->debug('Caching image information and formatted output to cacheKey ' . $cacheKey);
  186. $this->modx->cacheManager->set($cacheKey, $cached, 0, $this->cacheOptions);
  187. }
  188.  
  189. return $this->finish($formatted);
  190. }
  191.  
  192. /**
  193. *
  194. *
  195. * @return string
  196. * @throws \modmore\Alpacka\Exceptions\InvalidPropertyException
  197. */
  198. public function getImageCollection()
  199. {
  200. // Set the tags propery to include tags from the URL, so that the cacheKey is updated when tags change
  201. $this->setProperty('tags', $this->getTags());
  202. $random = in_array(strtolower($this->getProperty('sortBy')), array('random', 'rand', 'rand()'), true);
  203. $limit = $this->getProperty('limit');
  204.  
  205.  
  206. // Try to load from cache
  207. $cacheKey = 'image-collection/' . $this->getProperty('resource') . '/' . $this->getPropertyHash() . '_' . $this->getChunkHash();
  208. if ($this->getProperty('cache')) {
  209. $cached = $this->modx->cacheManager->get($cacheKey, $this->cacheOptions);
  210. if (is_array($cached)) {
  211. $this->debug('Loaded image collection from cache using cacheKey ' . $cacheKey);
  212.  
  213. $formatted = $cached['formatted'];
  214.  
  215. if ($random && array_key_exists('result_set', $cached)) {
  216. $this->debug('Randomising and parsing result set from cache.');
  217. shuffle($cached['result_set']);
  218.  
  219. if ($limit > 0) {
  220. $this->debug('Limiting result set to ' . $limit);
  221. $cached['result_set'] = array_slice($cached['result_set'], 0, $limit);
  222. }
  223.  
  224. $formatted = $this->parseCollection($cached['result_set'], $cached['total']);
  225. }
  226.  
  227. return $this->finish($formatted);
  228. }
  229. }
  230.  
  231. $this->debug('Preparing SQL query to retrieve images and related data.');
  232.  
  233. $c = $this->modx->newQuery('mgImage');
  234. $c->distinct(true);
  235.  
  236. $resource = $this->getProperty('resource');
  237. if (strpos($resource, ',') !== false) {
  238. $c->where(array(
  239. 'resource:IN' => explode(',', $resource),
  240. ));
  241. }
  242. else {
  243. $c->where(array(
  244. 'resource' => $resource,
  245. ));
  246. }
  247.  
  248. if ($this->getProperty('activeOnly')) {
  249. $c->where(array(
  250. 'active' => true,
  251. ));
  252. }
  253.  
  254. $customCondition = $this->getProperty('where');
  255. if (!empty($customCondition)) {
  256. $customConditionArray = json_decode($customCondition, true);
  257. if (is_array($customConditionArray)) {
  258. $c->where($customConditionArray);
  259. }
  260. else {
  261. $this->debug('WARNING: Custom condition ' . $customCondition . ' is not valid JSON.');
  262. }
  263. }
  264.  
  265. $this->addTagsCondition($c);
  266.  
  267. // Get the total and make it available for getPage support
  268. $this->debug('Fetching total count for query');
  269. $total = $this->modx->getCount('mgImage', $c);
  270. $this->debug('Total results: ' . $total);
  271. $this->modx->setPlaceholder($this->getProperty('totalVar'), $total);
  272.  
  273. // Apply the limit if we're not using a random sort
  274. if (!$random && $limit > 0) {
  275. $c->limit($limit, $this->getProperty('offset'));
  276. }
  277.  
  278. // Apply sorting if this isn't a random sort
  279. if (!$random) {
  280. $c->sortby($this->getProperty('sortBy'), $this->getProperty('sortDir'));
  281. }
  282. else {
  283. $c->sortby('RAND()');
  284. }
  285.  
  286. if ($this->getProperty('debug')) {
  287. $c->prepare();
  288. $this->debug('Executing query: ' . $c->toSQL());
  289. }
  290.  
  291. // Loop over the images and put them into $data
  292. $data = array();
  293. $i = 0;
  294. $this->debug('Iterating over images');
  295. /** @var mgImage[] $iterator */
  296. $iterator = $this->modx->getIterator('mgImage', $c);
  297.  
  298. $lastIndex = count($iterator) -1;
  299.  
  300. foreach ($iterator as $image) {
  301.  
  302. $phs = $this->getImagePlaceholders($image);
  303. $data[$i] = $phs;
  304.  
  305. // Add prev and next options
  306. if (isset($data[$i - 1])) {
  307. $data[$i]['prev'] = $data[$i - 1];
  308. $data[$i - 1]['next'] = $phs;
  309. // Prevent some sort of recursive array
  310. unset($data[$i]['prev']['prev']);
  311. }
  312. $i++;
  313. }
  314.  
  315. // If we're dealing with random images, the limit wasn't applied to the SQL query.
  316. // So we splice it here.
  317. $fullResultSet = $data;
  318. if ($random && $limit > 0) {
  319. $this->debug('Splicing result set for random sort');
  320. $data = array_splice($data, 0, $limit);
  321. }
  322.  
  323. $this->debug('Parsing image collection');
  324. // Loop over the items and parse them through the imageTpl
  325. $formatted = $this->parseCollection($data, $total);
  326.  
  327. // If cache is enabled, write the data to the proper cache file.
  328. if ($this->getProperty('cache')) {
  329. $this->debug('Caching formatted and raw results to ' . $cacheKey);
  330. $cached = array(
  331. 'total' => $total,
  332. 'formatted' => $formatted,
  333. 'result_set' => $fullResultSet,
  334. );
  335. $this->modx->cacheManager->set($cacheKey, $cached, 0, $this->cacheOptions);
  336. }
  337.  
  338. return $this->finish($formatted);
  339. }
  340.  
  341.  
  342. /**
  343. * Turns an image object into placeholders, including loading related data (crops, tags, url, resource stuff).
  344. *
  345. * @param mgImage $image
  346. * @return array
  347. */
  348. public function getImagePlaceholders(mgImage $image, $previousAndNext = false)
  349. {
  350. // Start collecting all placeholders with just the standard image info.
  351. $phs = $image->toArray();
  352.  
  353. $phs['idx'] = $this->_idx++;
  354.  
  355. // Get the crops for the image
  356. $phs['crops'] = $image->getCropsAsArray();
  357.  
  358. // Process the url placeholder into a link tag
  359. if (is_numeric($phs['url']) && $phs['url'] > 0) {
  360. $phs['url'] = '[[~' . $phs['url'] . ']]';
  361. }
  362.  
  363. // Generate a view_url placeholder for a detail page
  364. $singleImageResource = $this->getProperty('singleImageResource');
  365. if ($singleImageResource < 1) {
  366. $singleImageResource = $phs['resource'];
  367. }
  368. $phs['view_url'] = $this->modx->makeUrl($singleImageResource, '', array(
  369. $this->singleImageParam => $image->get('id'),
  370. ), $this->getProperty('scheme'));
  371.  
  372. // If requested, load all the resource fields
  373. if ($this->getProperty('getResourceFields')) {
  374. $phs = array_merge($phs, $this->getResourceFields($image->get('resource')));
  375. }
  376.  
  377. if ($previousAndNext) {
  378.  
  379. $first = $image->getFirst($this->getProperty('sortBy'), $this->getProperty('activeOnly'));
  380. if ($first instanceof mgImage) {
  381. $phs['first'] = $first->toArray();
  382. if (is_numeric($phs['first']['url']) && $phs['first']['url'] > 0) {
  383. $phs['first']['url'] = '[[~' . $phs['first']['url'] . ']]';
  384. }
  385. $phs['first']['view_url'] = $this->modx->makeUrl($singleImageResource, '', array(
  386. $this->singleImageParam => $first->get('id'),
  387. ), $this->getProperty('scheme'));
  388. $phs['first']['crops'] = $first->getCropsAsArray();
  389. }
  390.  
  391. $previous = $image->getPrevious($this->getProperty('sortBy'), $this->getProperty('activeOnly'));
  392. if ($previous instanceof mgImage) {
  393. $phs['prev'] = $previous->toArray();
  394. if (is_numeric($phs['prev']['url']) && $phs['prev']['url'] > 0) {
  395. $phs['prev']['url'] = '[[~' . $phs['prev']['url'] . ']]';
  396. }
  397. $phs['prev']['view_url'] = $this->modx->makeUrl($singleImageResource, '', array(
  398. $this->singleImageParam => $previous->get('id'),
  399. ), $this->getProperty('scheme'));
  400. $phs['prev']['crops'] = $previous->getCropsAsArray();
  401. }
  402.  
  403. $next = $image->getNext($this->getProperty('sortBy'), $this->getProperty('activeOnly'));
  404. if ($next instanceof mgImage) {
  405. $phs['next'] = $next->toArray();
  406. if (is_numeric($phs['next']['url']) && $phs['next']['url'] > 0) {
  407. $phs['next']['url'] = '[[~' . $phs['next']['url'] . ']]';
  408. }
  409. $phs['next']['view_url'] = $this->modx->makeUrl($singleImageResource, '', array(
  410. $this->singleImageParam => $next->get('id'),
  411. ), $this->getProperty('scheme'));
  412. $phs['next']['crops'] = $next->getCropsAsArray();
  413. }
  414.  
  415. $last = $image->getLast($this->getProperty('sortBy'), $this->getProperty('activeOnly'));
  416. if ($last instanceof mgImage) {
  417. $phs['last'] = $last->toArray();
  418. if (is_numeric($phs['last']['url']) && $phs['last']['url'] > 0) {
  419. $phs['last']['url'] = '[[~' . $phs['last']['url'] . ']]';
  420. }
  421. $phs['last']['view_url'] = $this->modx->makeUrl($singleImageResource, '', array(
  422. $this->singleImageParam => $last->get('id'),
  423. ), $this->getProperty('scheme'));
  424. $phs['last']['crops'] = $last->getCropsAsArray();
  425. }
  426.  
  427. // If the sortorder is descending, we need to swap out prev and next placeholders to keep things in order
  428. if ($this->getProperty('sortDir') === 'DESC') {
  429. $prev = isset($phs['prev']) ? $phs['prev'] : null;
  430. $phs['prev'] = isset($phs['next']) ? $phs['next'] : null;
  431. $phs['next'] = $prev;
  432. }
  433. //ppb-todo do this for first an last
  434. }
  435.  
  436. if ($this->getProperty('getTags')) {
  437. $phs['tags_raw'] = $image->getTags();
  438. $phs['tags'] = array();
  439. foreach ($phs['tags_raw'] as $tag) {
  440. $phs['tags'][] = $this->service->getChunk($this->getProperty('tagTpl'), $tag);
  441. }
  442. $phs['tags'] = implode($this->getProperty('tagSeparator'), $phs['tags']);
  443. }
  444.  
  445. // Return it
  446. return $phs;
  447. }
  448.  
  449. /**
  450. * Returns an array of resource fields (if the resource can be loaded, otherwise an empty array)
  451. *
  452. * @param $resourceId
  453. * @return array
  454. */
  455. public function getResourceFields($resourceId)
  456. {
  457. // See if we already have the resource data available as an array, if so return it.
  458. if (array_key_exists($resourceId, $this->_resourceData)) {
  459. return $this->_resourceData[$resourceId];
  460. }
  461.  
  462. // See if we already have the resource, if not load it.
  463. if (!array_key_exists($resourceId, $this->_resources)) {
  464. $this->_resources[$resourceId] = $this->modx->getObject('modResource', (int)$resourceId);
  465. }
  466.  
  467. // Local alias just to make it easier
  468. $resource = $this->_resources[$resourceId];
  469.  
  470. // Make sure it's a modResource and then grab the data
  471. if ($resource instanceof modResource) {
  472. $data = $resource->get($this->resourceFields);
  473.  
  474. // Only get the content if specifically requested
  475. if ($this->getProperty('getResourceContent')) {
  476. $data['content'] = $resource->get('content');
  477. }
  478.  
  479. // Only get the properties field if specifically requested
  480. if ($this->getProperty('getResourceProperties')) {
  481. $data['properties'] = $resource->get('properties');
  482. }
  483.  
  484. // Load the TVs that the user requested
  485. $tvs = $this->getProperty('getResourceTVs');
  486. if (!empty($tvs)) {
  487. $tvs = explode(',', $tvs);
  488.  
  489. foreach ($tvs as $tv) {
  490. $data[$tv] = $resource->getTVValue($tv);
  491. }
  492. }
  493.  
  494. // Prefix 'resource.' to the values so we don't have to conflict with mgImage.resource
  495. $data = $this->prefix($data, 'resource.');
  496.  
  497. // Store a local copy of it so we don't have to do this over and over
  498. $this->_resourceData[$resourceId] = $data;
  499.  
  500. // Return it
  501. return $data;
  502. }
  503. return array();
  504. }
  505.  
  506. /**
  507. * Prefixes the data with the specified prefix.
  508. *
  509. * @param $data
  510. * @return array
  511. */
  512. public function prefix($data, $prefix)
  513. {
  514. $prefixed = array();
  515. foreach ($data as $key => $value) {
  516. $prefixed[$prefix . $key] = $value;
  517. }
  518. return $prefixed;
  519. }
  520.  
  521. /**
  522. * Finishes the snippet by either returning the snippet output or by setting a requested placeholder.
  523. *
  524. * @param $formatted
  525. * @return string
  526. */
  527. public function finish($formatted)
  528. {
  529. $this->debug('Finished processing, outputting results.');
  530.  
  531. if ($this->getProperty('debug')) {
  532. $formatted .= '<h3>Debug Information</h3><pre>' . print_r($this->_debug, true) . '</pre>';
  533. }
  534.  
  535. if ($this->getProperty('timing')) {
  536. $time = microtime(true);
  537. $spent = ($time - $this->_startTime) * 1000;
  538. $formatted .= '<p>Finished in ' . number_format($spent, 2) . 'ms</p>';
  539. }
  540.  
  541. if ($placeholder = $this->getProperty('toPlaceholder')) {
  542. $this->modx->setPlaceholder($placeholder, $formatted);
  543. return '';
  544. }
  545. return $formatted;
  546. }
  547.  
  548. /**
  549. * Gets a comma separated list of tags. This is either the defined tags in the snippet call,
  550. * or provided by a $_REQUEST parameter if &tagsFromUrl is specified and filled.
  551. *
  552. * @return string
  553. */
  554. public function getTags()
  555. {
  556. $rawTags = $this->getProperty('tags');
  557. $param = $this->getProperty('tagsFromUrl');
  558. if (isset($_REQUEST[$param])) {
  559. $rawTags = $_REQUEST[$param];
  560. }
  561. $rawTags = explode(',', $rawTags);
  562.  
  563. // Sanitise tags
  564. $tags = array();
  565. foreach ($rawTags as $tag) {
  566. $tags[] = $this->modx->sanitizeString($tag);
  567. }
  568.  
  569. return implode(',', $tags);
  570. }
  571.  
  572. /**
  573. * This method adds the conditionals for tags to the collection query.
  574. *
  575. * @param xPDOQuery $c
  576. */
  577. public function addTagsCondition(xPDOQuery $c)
  578. {
  579. $allTagIds = $this->service->getTagIds();
  580. $tagIds = array();
  581. $excludedTagIds = array();
  582.  
  583. // Loop over the requested tags to find their respective IDs
  584. $tags = $this->getProperty('tags');
  585. $tags = explode(',', $tags);
  586. if (count($tags) > 0) {
  587. $this->debug('Adding conditions for tags: ' . implode(', ', $tags));
  588. foreach ($tags as $tag) {
  589. $exclude = strpos($tag, '-') === 0;
  590. $tag = ($exclude) ? substr($tag, 1) : $tag;
  591. if (is_numeric($tag)) {
  592. if (!$exclude) {
  593. $tagIds[] = (int)$tag;
  594. } else {
  595. $excludedTagIds[] = (int)$tag;
  596. }
  597. } else {
  598. $search = array_search($tag, $allTagIds, true);
  599. if (is_numeric($search) && $search > 0) {
  600. if (!$exclude) {
  601. $tagIds[] = $search;
  602. } else {
  603. $excludedTagIds[] = $search;
  604. }
  605. }
  606. }
  607. }
  608.  
  609.  
  610. // If we have tags to include, add 'm to the query
  611. if (!empty($tagIds)) {
  612. $this->debug('Including tag IDs: ' . implode(', ', $tagIds));
  613. $c->leftJoin('mgImageTag', 'Tags');
  614. $c->where(array(
  615. 'Tags.tag:IN' => $tagIds,
  616. ));
  617. }
  618.  
  619. // If we have tags to exclude, get rid of 'm
  620. if (!empty($excludedTagIds)) {
  621. $this->debug('Excluding tag IDs: ' . implode(', ', $excludedTagIds));
  622. $excludedTagIds = implode(',', $excludedTagIds);
  623. $c->where(array(
  624. "NOT EXISTS (SELECT 1 FROM {$this->modx->getTableName('mgImageTag')} Tags WHERE `mgImage`.`id` = `Tags`.`image` AND `Tags`.`tag` IN ({$excludedTagIds}))"
  625. ));
  626. }
  627. }
  628. }
  629.  
  630. /**
  631. * Parses collection data into markup.
  632. *
  633. * @param $data
  634. * @param $total
  635. * @return string
  636. */
  637. public function parseCollection($data, $total)
  638. {
  639. $formattedArr = array();
  640. foreach ($data as $phs) {
  641. $tpl = $this->determineTpl($phs);
  642. $formattedArr[] = $this->service->getChunk($tpl, $phs);
  643. }
  644. $formatted = implode($this->getProperty('imageSeparator'), $formattedArr);
  645.  
  646. // Apply the wrapper template
  647. $wrapperTpl = $this->getProperty('wrapperTpl');
  648. if (!empty($wrapperTpl)) {
  649. $wrapperIfEmpty = $this->getProperty('wrapperIfEmpty');
  650. if (!empty($formatted) || $wrapperIfEmpty) {
  651. $phs = array_merge(array(
  652. 'output' => $formatted,
  653. 'image_count' => $total,
  654. ), $this->getResourceFields($this->getProperty('resource')));
  655.  
  656. $formatted = $this->service->getChunk($wrapperTpl, $phs);
  657. }
  658. }
  659.  
  660. return $formatted;
  661. }
  662.  
  663. /**
  664. * Returns the template (chunk name) to use for this item.
  665. *
  666. * @param $data
  667. * @return string
  668. */
  669. public function determineTpl($data)
  670. {
  671. switch ($data['class_key']) {
  672. case 'mgYouTubeVideo':
  673. case 'mgVideo':
  674. return $this->getProperty('youtubeTpl');
  675.  
  676. case 'mgVimeoVideo':
  677. return $this->getProperty('vimeoTpl');
  678.  
  679. case 'mgImage':
  680. default:
  681. return $this->getProperty('imageTpl');
  682. }
  683. }
  684.  
  685. /**
  686. * Returns the template (chunk name) to use for a single item being displayed.
  687. *
  688. * @param $data
  689. * @return string
  690. */
  691. public function determineSingleTpl($data)
  692. {
  693. switch ($data['class_key']) {
  694. case 'mgYouTubeVideo':
  695. case 'mgVideo':
  696. return $this->getProperty('singleYoutubeTpl');
  697.  
  698. case 'mgVimeoVideo':
  699. return $this->getProperty('singleVimeoTpl');
  700.  
  701. case 'mgImage':
  702. default:
  703. return $this->getProperty('singleImageTpl');
  704. }
  705. }
  706.  
  707. /**
  708. * Generates a sha1 hash for the (unparsed) content of all chunks used by this snippet call. This is used for
  709. * automatically busting the relevant caches when a chunk is changed.
  710. *
  711. * @return string
  712. */
  713. public function getChunkHash()
  714. {
  715. if (empty($this->chunkHash)) {
  716. $props = array(
  717. 'tagTpl',
  718. 'imageTpl',
  719. 'youtubeTpl',
  720. 'vimeoTpl',
  721. 'singleImageTpl',
  722. 'singleYoutubeTpl',
  723. 'singleVimeoTpl'
  724. );
  725. $chunks = array();
  726. foreach ($props as $tplProp) {
  727. $chunks[] = $this->getProperty($tplProp);
  728. }
  729.  
  730. $chunks = array_unique($chunks);
  731.  
  732. $this->debug('Calculating chunkHash (for automatic cache-busting) for chunks: ' . implode(',', $chunks));
  733.  
  734. $c = $this->modx->newQuery('modChunk');
  735. $c->where(array('name:IN' => $chunks));
  736. $c->select($this->modx->getSelectColumns('modChunk', 'modChunk', '', array('id', 'name', 'snippet')));
  737.  
  738. $c->prepare();
  739. $sql = $c->toSQL();
  740.  
  741. $chunkContents = array();
  742. $result = $this->modx->query($sql);
  743. while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
  744. $chunkContents[] = $row['snippet'];
  745. }
  746.  
  747. $chunkContents = implode(',', $chunkContents);
  748. $this->chunkHash = sha1(sha1($chunkContents));
  749.  
  750. $chunkContents = str_replace(array('[', ']'), array('&#91;', '&#93;'), htmlentities($chunkContents, ENT_QUOTES, 'utf-8'));
  751. $this->debug('chunkHash calculated as ' . $this->chunkHash . ' based on raw content ' . $chunkContents);
  752. }
  753.  
  754. return $this->chunkHash;
  755. }
  756.  
  757. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement