Overview

Namespaces

  • rsanchez
    • Deep
      • App
        • EE
        • Laravel
          • Facade
      • Collection
      • Hydrator
      • Model
      • Plugin
      • Relations
      • Repository

Classes

  • BasePlugin
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Deep
  5:  *
  6:  * @package      rsanchez\Deep
  7:  * @author       Rob Sanchez <info@robsanchez.com>
  8:  */
  9: 
 10: namespace rsanchez\Deep\Plugin;
 11: 
 12: use rsanchez\Deep\Deep;
 13: use rsanchez\Deep\Model\Entry;
 14: use rsanchez\Deep\Model\Category;
 15: use rsanchez\Deep\Collection\AbstractTitleCollection;
 16: use rsanchez\Deep\Collection\RelationshipCollection;
 17: use rsanchez\Deep\Collection\FilterableInterface;
 18: use rsanchez\Deep\Collection\CategoryCollection;
 19: use Illuminate\Support\Collection;
 20: use DateTime;
 21: use Closure;
 22: 
 23: /**
 24:  * Base class for EE modules/plugins
 25:  */
 26: abstract class BasePlugin
 27: {
 28:     /**
 29:      * @var \rsanchez\Deep\Deep
 30:      */
 31:     protected $app;
 32: 
 33:     /**
 34:      * @var \Pagination_object
 35:      */
 36:     protected $paginator;
 37: 
 38:     /**
 39:      * Constructor
 40:      * @return void
 41:      */
 42:     public function __construct()
 43:     {
 44:         $this->app = Deep::getInstance();
 45: 
 46:         $this->app->bootEE(ee());
 47: 
 48:         ee()->load->library(array('pagination', 'typography'));
 49:     }
 50: 
 51:     /**
 52:      * Get the default tag parameters when using parseEntries
 53:      *
 54:      * @return array
 55:      */
 56:     protected function getEntriesDefaultParameters()
 57:     {
 58:         return array(
 59:             'dynamic' => 'yes',
 60:             'limit' => '100',
 61:             'orderby' => 'entry_date',
 62:             'paginate' => 'bottom',
 63:             'show_future_entries' => 'no',
 64:             'show_expired' => 'no',
 65:             'sort' => 'desc',
 66:             'status' => 'open',
 67:         );
 68:     }
 69: 
 70:     /**
 71:      * Get the default tag parameters when using parseEntries
 72:      *
 73:      * @return array
 74:      */
 75:     protected function getCategoriesDefaultParameters()
 76:     {
 77:         return array(
 78:             'show_empty' => 'yes',
 79:             'show_future_entries' => 'no',
 80:             'show_expired' => 'no',
 81:             'restrict_channel' => 'yes',
 82:             'style' => 'nested',
 83:             'id' => 'nav_categories',
 84:             'orderby' => 'categories.group_id|categories.parent_id|categories.cat_order',
 85:         );
 86:     }
 87: 
 88:     /**
 89:      * Get an EntryCollection based on the state of ee()->TMPL
 90:      *
 91:      * @param  Closure|null                              $callback receieves a query builder object as the first parameter
 92:      * @return \rsanchez\Deep\Collection\EntryCollection
 93:      */
 94:     protected function getEntries(Closure $callback = null)
 95:     {
 96:         foreach ($this->getEntriesDefaultParameters() as $key => $value) {
 97:             if (! isset(ee()->TMPL->tagparams[$key])) {
 98:                 ee()->TMPL->tagparams[$key] = $value;
 99:             }
100:         }
101: 
102:         $disabled = empty(ee()->TMPL->tagparams['disable']) ? array() : explode('|', ee()->TMPL->tagparams['disable']);
103: 
104:         $this->paginator = ee()->pagination->create();
105: 
106:         $limit = ee()->TMPL->fetch_param('limit');
107: 
108:         ee()->TMPL->tagdata = $this->paginator->prepare(ee()->TMPL->tagdata);
109: 
110:         $customFieldsEnabled = ! in_array('custom_fields', $disabled);
111:         $memberDataEnabled = ! in_array('members', $disabled);
112:         $paginationEnabled = ! in_array('pagination', $disabled);
113:         $categoriesEnabled = ! in_array('categories', $disabled);
114:         $categoryFieldsEnabled = $categoriesEnabled && ! in_array('category_fields', $disabled);
115: 
116:         if ($limit && $paginationEnabled) {
117:             unset(ee()->TMPL->tagparams['offset']);
118:         } else {
119:             $this->paginator->paginate = false;
120:         }
121: 
122:         $uri = ee()->uri->page_query_string ?: ee()->uri->query_string;
123: 
124:         if (preg_match('#^((.*?)/)?P\d+/?$#', $uri, $match)) {
125:             $uri = $match[2];
126:         }
127: 
128:         if (! $uri && ee()->TMPL->fetch_param('require_entry') === 'yes') {
129:             return ee()->TMPL->no_results();
130:         }
131: 
132:         ee()->TMPL->tagparams['category_request'] = false;
133: 
134:         $singleEntry = false;
135: 
136:         $relatedCategoriesMode = ee()->TMPL->fetch_param('related_categories_mode') === 'yes';
137: 
138:         $dynamic = ee()->TMPL->fetch_param('dynamic', 'yes') === 'yes';
139: 
140:         $query = $this->app->make($customFieldsEnabled ? 'Entry' : 'Title')->newQuery();
141: 
142:         if ($uri && ($dynamic || $relatedCategoriesMode)) {
143:             $segments = explode('/', $uri);
144:             $lastSegment = array_pop($segments);
145:             $penultimateSegment = array_pop($segments);
146: 
147:             if (preg_match('#(^|/)(\d{4})/(\d{2})(/(\d{2}))?/?$#', $uri, $match)) {
148:                 ee()->TMPL->tagparams['year'] = $match[2];
149:                 ee()->TMPL->tagparams['month'] = $match[3];
150: 
151:                 if (isset($match[5])) {
152:                     ee()->TMPL->tagparams['day'] = $match[5];
153:                 }
154:             } elseif (is_numeric($lastSegment)) {
155:                 if ($relatedCategoriesMode) {
156:                     $singleEntry = true;
157:                     $query->relatedCategories($lastSegment);
158:                     ee()->TMPL->tagparams['dynamic'] = 'no';
159:                 } else {
160:                     ee()->TMPL->tagparams['entry_id'] = $lastSegment;
161:                 }
162:             } elseif (
163:                 ee()->config->item('use_category_name') === 'y' &&
164:                 $penultimateSegment === ee()->config->item('reserved_category_word')
165:             ) {
166:                 ee()->TMPL->tagparams['category_name'] = $lastSegment;
167: 
168:                 ee()->TMPL->tagparams['category_request'] = true;
169:             } elseif (
170:                 ee()->config->item('use_category_name') !== 'y' &&
171:                 preg_match('#(^|/)C(\d+)#', $uri, $match)
172:             ) {
173:                 ee()->TMPL->tagparams['category'] = $match[2];
174: 
175:                 ee()->TMPL->tagparams['category_request'] = true;
176:             } else {
177:                 if ($relatedCategoriesMode) {
178:                     $singleEntry = true;
179:                     $query->relatedCategoriesUrlTitle($lastSegment);
180:                     ee()->TMPL->tagparams['dynamic'] = 'no';
181:                 } else {
182:                     ee()->TMPL->tagparams['url_title'] = $lastSegment;
183:                 }
184:             }
185:         }
186: 
187:         if ($relatedCategoriesMode && ! $singleEntry) {
188:             return ee()->TMPL->no_results();
189:         }
190: 
191:         $query->tagparams(ee()->TMPL->tagparams);
192: 
193:         if ($categoriesEnabled) {
194:             $query->withCategories(function ($query) use ($categoryFieldsEnabled) {
195:                 if ($categoryFieldsEnabled) {
196:                     $query->withFields();
197:                 }
198: 
199:                 return $query->orderBy('categories.group_id')
200:                     ->orderBy('categories.parent_id')
201:                     ->orderBy('categories.cat_order');
202:             });
203:         }
204: 
205:         if ($memberDataEnabled) {
206:             $query->withAuthorFields();
207:         }
208: 
209:         $connection = $query->getQuery()->getConnection();
210:         $tablePrefix = $connection->getTablePrefix();
211: 
212:         if (strpos(ee()->TMPL->tagdata, 'comment_subscriber_total') !== false) {
213:             $subquery = "(select count(*) "
214:                 ."from `{$tablePrefix}comment_subscriptions` "
215:                 ."where `{$tablePrefix}comment_subscriptions`.`entry_id` "
216:                 ."= `{$tablePrefix}`channel_titles`.`entry_id`) "
217:                 ."as `comment_subscriber_total`";
218: 
219:             $query->addSelect($connection->raw($subquery));
220:         }
221: 
222:         $prefix = ee()->TMPL->fetch_param('var_prefix') ? ee()->TMPL->fetch_param('var_prefix').':' : '';
223: 
224:         if (strpos(ee()->TMPL->tagdata, '{'.$prefix.'parents') !== false) {
225:             $query->withParents();
226:         }
227: 
228:         if (strpos(ee()->TMPL->tagdata, '{'.$prefix.'siblings') !== false) {
229:             $query->withSiblings();
230:         }
231: 
232:         if (is_callable($callback)) {
233:             $callback($query);
234:         }
235: 
236:         ee()->TMPL->tagparams['absolute_results'] = $limit;
237: 
238:         if ($this->paginator->paginate) {
239:             ee()->TMPL->tagparams['absolute_results'] = $query->getQuery()->getPaginationCount();
240: 
241:             $this->paginator->build(ee()->TMPL->tagparams['absolute_results'], $limit);
242: 
243:             if ($this->paginator->offset) {
244:                 $query->skip($this->paginator->offset);
245: 
246:                 ee()->TMPL->tagparams['offset'] = $this->paginator->offset;
247:             }
248:         }
249: 
250:         return $query->get();
251:     }
252: 
253:     /**
254:      * Parse a plugin tag pair equivalent to channel:entries
255:      *
256:      * @param  Closure|null $callback receieves a query builder object as the first parameter
257:      * @return string
258:      */
259:     public function parseEntries(Closure $callback = null)
260:     {
261:         $entries = $this->getEntries($callback);
262: 
263:         $output = $this->parseEntryCollection(
264:             $entries,
265:             ee()->TMPL->tagdata,
266:             ee()->TMPL->tagparams,
267:             ee()->TMPL->var_pair,
268:             ee()->TMPL->var_single
269:         );
270: 
271:         if ($this->paginator->paginate) {
272:             $output = $this->paginator->render($output);
273:         }
274: 
275:         return $output;
276:     }
277: 
278:     /**
279:      * Parse a plugin tag pair equivalent to channel:entries
280:      *
281:      * @param  AbstractTitleCollection $entries   a collection of entries
282:      * @param  string                  $tagdata   the raw template to parse
283:      * @param  array                   $params    channel:entries parameters
284:      * @param  array                   $varPair   array of pair tags from ee()->functions->assign_variables
285:      * @param  array                   $varSingle array single tags from ee()->functions->assign_variables
286:      * @return string
287:      */
288:     protected function parseEntryCollection(
289:         AbstractTitleCollection $entries,
290:         $tagdata,
291:         array $params = array(),
292:         array $varPair = array(),
293:         array $varSingle = array()
294:     ) {
295:         $disabled = empty($params['disable']) ? array() : explode('|', $disable);
296: 
297:         $offset = isset($params['offset']) ? $params['offset'] : 0;
298: 
299:         $absoluteResults = isset($params['absolute_results']) ? $params['absolute_results'] : $entries->count();
300: 
301:         $customFieldsEnabled = ! in_array('custom_fields', $disabled);
302:         $memberDataEnabled = ! in_array('member_data', $disabled);
303:         $categoriesEnabled = ! in_array('categories', $disabled);
304:         $categoryFieldsEnabled = $categoriesEnabled && ! in_array('category_fields', $disabled);
305: 
306:         ee()->load->library('typography');
307: 
308:         if (! empty($params['var_prefix'])) {
309:             $prefix = rtrim($params['var_prefix'], ':').':';
310:             $prefixLength = strlen($prefix);
311:         } else {
312:             $prefix = '';
313:             $prefixLength = 0;
314:         }
315: 
316:         $singleTags = array();
317:         $pairTags = array();
318: 
319:         foreach (array_keys($varSingle) as $tag) {
320:             $spacePosition = strpos($tag, ' ');
321: 
322:             if ($spacePosition !== false) {
323:                 $name = substr($tag, 0, $spacePosition);
324:                 $tagparams = ee()->functions->assign_parameters(substr($tag, $spacePosition));
325:             } elseif (preg_match('#^([a-z_]+)=([\042\047]?)?(.*?)\\2$#', $tag, $match)) {
326:                 $name = $match[1];
327:                 $tagparams = $match[3] ? array($match[3]) : array('');
328:             } else {
329:                 $name = $tag;
330:                 $tagparams = array();
331:             }
332: 
333:             if ($prefix && strncmp($name, $prefix, $prefixLength) !== 0) {
334:                 continue;
335:             }
336: 
337:             $singleTags[] = (object) array(
338:                 'name' => $prefix ? substr($name, $prefixLength) : $name,
339:                 'key' => $tag,
340:                 'params' => $tagparams,
341:                 'tagdata' => '',
342:             );
343:         }
344: 
345:         foreach ($varPair as $tag => $tagparams) {
346:             $spacePosition = strpos($tag, ' ');
347: 
348:             $name = $spacePosition === false ? $tag : substr($tag, 0, $spacePosition);
349: 
350:             if ($prefix && strncmp($name, $prefix, $prefixLength) !== 0) {
351:                 continue;
352:             }
353: 
354:             preg_match_all('#{('.preg_quote($tag).'}(.*?){/'.preg_quote($name).')}#s', $tagdata, $matches);
355: 
356:             foreach ($matches[1] as $i => $key) {
357:                 $pairTags[] = (object) array(
358:                     'name' => $prefix ? substr($name, $prefixLength) : $name,
359:                     'key' => $key,
360:                     'params' => $tagparams ?: array(),
361:                     'tagdata' => $matches[2][$i],
362:                 );
363:             }
364:         }
365: 
366:         $variables = array();
367: 
368:         foreach ($entries as $i => $entry) {
369:             $row = array(
370:                 $prefix.'absolute_count' => $offset + $i + 1,
371:                 $prefix.'absolute_results' => $absoluteResults,
372:                 $prefix.'category_request' => isset($params['category_request']) ? $params['category_request'] : false,
373:                 $prefix.'not_category_request' => isset($params['category_request']) ? ! $params['category_request'] : true,
374:                 $prefix.'channel' => $entry->channel->channel_name,
375:                 $prefix.'channel_short_name' => $entry->channel->channel_name,
376:                 $prefix.'comment_auto_path' => $entry->channel->comment_url,
377:                 $prefix.'comment_entry_id_auto_path' => $entry->channel->comment_url.'/'.$entry->entry_id,
378:                 $prefix.'comment_url_title_auto_path' => $entry->channel->comment_url.'/'.$entry->url_title,
379:                 $prefix.'entry_site_id' => $entry->site_id,
380:                 $prefix.'forum_topic' => (int) (bool) $entry->forum_topic_id,
381:                 $prefix.'not_forum_topic' => (int) ! $entry->forum_topic_id,
382:                 $prefix.'page_uri' => $entry->page_uri,
383:                 $prefix.'page_url' => ee()->functions->create_url($entry->page_uri),
384:                 $prefix.'entry_id_path' => array($entry->entry_id, array('path_variable' => true)),
385:                 $prefix.'permalink' => array($entry->entry_id, array('path_variable' => true)),
386:                 $prefix.'title_permalink' => array($entry->url_title, array('path_variable' => true)),
387:                 $prefix.'url_title_path' => array($entry->url_title, array('path_variable' => true)),
388:                 $prefix.'profile_path' => array($entry->author_id, array('path_variable' => true)),
389:             );
390: 
391:             foreach ($pairTags as $tag) {
392:                 if ($tag->name === 'parents' || $tag->name === 'siblings') {
393:                     $value = $entry->{$tag->name};
394: 
395:                     $tag->params['var_prefix'] = $prefix.$tag->name;
396:                     $tag->vars = ee()->functions->assign_variables($tag->tagdata);
397: 
398:                     if (! empty($tag->params['field'])) {
399:                         $fieldRepository = $this->app->make('FieldRepository');
400: 
401:                         $fieldIds = array();
402: 
403:                         foreach (explode('|', $tag->params['field']) as $fieldName) {
404:                             if ($fieldRepository->hasField($fieldName)) {
405:                                 $fieldIds[] = $fieldRepository->getFieldId($fieldName);
406:                             }
407:                         }
408: 
409:                         if ($fieldIds) {
410:                             $tag->params['field_id'] = implode('|', $fieldIds);
411:                         }
412: 
413:                         unset($tag->params['field']);
414:                     }
415: 
416:                     $row[$tag->key] = $this->parseEntryCollection(
417:                         $value($tag->params),
418:                         $tag->tagdata,
419:                         $tag->params,
420:                         $tag->vars['var_pair'],
421:                         $tag->vars['var_single']
422:                     );
423:                 } elseif ($categoriesEnabled && $tag->name === 'categories') {
424: 
425:                     $categories = array();
426: 
427:                     foreach ($entry->categories->tagparams($tag->params) as $categoryModel) {
428:                         $category = $categoryModel->toArray();
429: 
430:                         unset(
431:                             $category['cat_id'],
432:                             $category['cat_name'],
433:                             $category['cat_description'],
434:                             $category['cat_image'],
435:                             $category['cat_url_title'],
436:                             $category['group_id']
437:                         );
438: 
439:                         $categoryUri = ee()->config->item('use_category_name') === 'y'
440:                             ? '/'.ee()->config->item('reserved_category_word').'/'.$categoryModel->cat_url_title
441:                             : '/C'.$categoryModel->cat_id;
442: 
443:                         $regex = '#'.preg_quote($categoryUri).'(\/|\/P\d+\/?)?$#';
444: 
445:                         $category['active'] = (bool) preg_match($regex, ee()->uri->uri_string());
446:                         $category['category_description'] = $categoryModel->cat_description;
447:                         $category['category_group'] = $categoryModel->group_id;
448:                         $category['category_id'] = $categoryModel->cat_id;
449:                         $category['category_image'] = $categoryModel->cat_image;
450:                         $category['category_name'] = $categoryModel->cat_name;
451:                         $category['category_url_title'] = $categoryModel->cat_url_title;
452:                         $category['path'] = array($categoryUri, array('path_variable' => true));
453: 
454:                         array_push($categories, $category);
455:                     }
456: 
457:                     // @TODO parse the file path at the model attribute level using upload pref repository
458:                     $row[$tag->key] = $categories ? ee()->typography->parse_file_paths(ee()->TMPL->parse_variables($tag->tagdata, $categories)) : '';
459: 
460:                 } elseif ($customFieldsEnabled && $entry->channel->fields->hasField($tag->name)) {
461: 
462:                     $row[$tag->key] = '';
463: 
464:                     $value = $entry->{$tag->name};
465: 
466:                     if ($value instanceof AbstractTitleCollection) {
467:                         // native relationships are prefixed by default
468:                         if ($value instanceof RelationshipCollection) {
469:                             $tag->params['var_prefix'] = $tag->name;
470:                         }
471: 
472:                         $tag->vars = ee()->functions->assign_variables($tag->tagdata);
473: 
474:                         $value = $this->parseEntryCollection(
475:                             $value($tag->params),
476:                             $tag->tagdata,
477:                             $tag->params,
478:                             $tag->vars['var_pair'],
479:                             $tag->vars['var_single']
480:                         );
481:                     } elseif ($value instanceof FilterableInterface) {
482:                         $value = $value($tag->params)->toArray();
483:                     } elseif (is_object($value) && method_exists($value, 'toArray')) {
484:                         $value = $value->toArray();
485:                     } elseif ($value) {
486:                         $value = (string) $value;
487:                     }
488: 
489:                     if ($value) {
490:                         if (is_array($value)) {
491:                             $row[$tag->key] = ee()->TMPL->parse_variables($tag->tagdata, $value);
492: 
493:                             if (isset($tag->params['backspace'])) {
494:                                 $row[$tag->key] = substr($row[$tag->key], 0, -$tag->params['backspace']);
495:                             }
496:                         } else {
497:                             $row[$tag->key] = $value;
498:                         }
499:                     }
500:                 }
501:             }
502: 
503:             foreach ($singleTags as $tag) {
504:                 if ($customFieldsEnabled && $entry->channel->fields->hasField($tag->name)) {
505:                     $row[$tag->key] = (string) $entry->{$tag->name};
506:                 }
507: 
508:                 if ($entry->{$tag->name} instanceof DateTime) {
509:                     $format = isset($tag->params['format']) ? preg_replace('#%([a-zA-Z])#', '\\1', $tag->params['format']) : 'U';
510: 
511:                     $row[$tag->key] = $entry->{$tag->name}->format($format);
512:                 }
513:             }
514: 
515:             foreach ($entry->getOriginal() as $key => $value) {
516:                 $row[$prefix.$key] = $value;
517:             }
518: 
519:             foreach ($entry->channel->toArray() as $key => $value) {
520:                 $row[$prefix.$key] = $value;
521:             }
522: 
523:             $row[$prefix.'allow_comments'] = (int) ($entry->allow_comments === 'y');
524:             $row[$prefix.'sticky'] = (int) ($entry->sticky === 'y');
525: 
526:             if ($memberDataEnabled) {
527:                 foreach ($entry->author->toArray() as $key => $value) {
528:                     $row[$prefix.$key] = $value;
529:                 }
530: 
531:                 $row[$prefix.'author'] = $entry->author->screen_name ?: $entry->author->username;
532:                 $row[$prefix.'avatar_url'] = $entry->author->avatar_filename ? ee()->config->item('avatar_url').$entry->author->avatar_filename : '';
533:                 $row[$prefix.'avatar_image_height'] = $entry->author->avatar_height;
534:                 $row[$prefix.'avatar_image_width'] = $entry->author->avatar_width;
535:                 $row[$prefix.'avatar'] = (int) (bool) $entry->author->avatar_filename;
536:                 $row[$prefix.'photo_url'] = $entry->author->photo_filename ? ee()->config->item('photo_url').$entry->author->photo_filename : '';
537:                 $row[$prefix.'photo_image_height'] = $entry->author->photo_height;
538:                 $row[$prefix.'photo_image_width'] = $entry->author->photo_width;
539:                 $row[$prefix.'photo'] = (int) (bool) $entry->author->photo_filename;
540:                 $row[$prefix.'signature_image_url'] = $entry->author->sig_img_filename ? ee()->config->item('sig_img_url').$entry->author->sig_img_filename : '';
541:                 $row[$prefix.'signature_image_height'] = $entry->author->sig_img_height;
542:                 $row[$prefix.'signature_image_width'] = $entry->author->sig_img_width;
543:                 $row[$prefix.'signature_image'] = (int) (bool) $entry->author->sig_img_filename;
544:                 $row[$prefix.'url_or_email'] = $entry->author->url ?: $entry->author->email;
545:                 $row[$prefix.'url_or_email_as_author'] = '<a href="'.($entry->author->url ?: 'mailto:'.$entry->author->email).'">'.$row[$prefix.'author'].'</a>';
546:                 $row[$prefix.'url_or_email_as_link'] = '<a href="'.($entry->author->url ?: 'mailto:'.$entry->author->email).'">'.$row[$prefix.'url_or_email'].'</a>';
547:             }
548: 
549:             $variables[] = $row;
550:         }
551: 
552:         if (preg_match('#{if '.preg_quote($prefix).'no_results}(.*?){/if}#s', $tagdata, $match)) {
553:             $tagdata = str_replace($match[0], '', $tagdata);
554:             ee()->TMPL->no_results = $match[1];
555:         }
556: 
557:         if (! $variables) {
558:             return ee()->TMPL->no_results();
559:         }
560: 
561:         $output = ee()->TMPL->parse_variables($tagdata, $variables);
562: 
563:         if (! empty($params['backspace'])) {
564:             $output = substr($output, 0, -$params['backspace']);
565:         }
566: 
567:         return $output;
568:     }
569: 
570:     /**
571:      * Parse a plugin tag pair equivalent to channel:categories
572:      *
573:      * @param  Closure|null $callback receieves a query builder object as the first parameter
574:      * @return string
575:      */
576:     protected function parseCategories(Closure $callback = null)
577:     {
578:         foreach ($this->getCategoriesDefaultParameters() as $key => $value) {
579:             if (! isset(ee()->TMPL->tagparams[$key])) {
580:                 ee()->TMPL->tagparams[$key] = $value;
581:             }
582:         }
583: 
584:         $query = $this->app->make('Category')->nested()->tagparams(ee()->TMPL->tagparams);
585: 
586:         $customFieldsEnabled = ee()->TMPL->fetch_param('disable') !== 'category_fields';
587: 
588:         if ($customFieldsEnabled) {
589:             $query->withFields();
590:         }
591: 
592:         if (is_callable($callback)) {
593:             $callback($query);
594:         }
595: 
596:         $categories = $query->get();
597: 
598:         $prefix = ee()->TMPL->fetch_param('var_prefix') ? ee()->TMPL->fetch_param('var_prefix').':' : '';
599: 
600:         if (preg_match('#{if '.preg_quote($prefix).'no_results}(.*?){/if}#s', ee()->TMPL->tagdata, $match)) {
601:             ee()->TMPL->tagdata = str_replace($match[0], '', ee()->TMPL->tagdata);
602:             ee()->TMPL->no_results = $match[1];
603:         }
604: 
605:         if ($categories->isEmpty()) {
606:             return ee()->TMPL->no_results();
607:         }
608: 
609:         if (ee()->TMPL->fetch_param('style') === 'nested') {
610:             $output = '<ul id="'.ee()->TMPL->fetch_param('id', 'nav_categories').'" class="'.ee()->TMPL->fetch_param('class', 'nav_categories').'">';
611: 
612:             foreach ($categories as $category) {
613:                 $output .= $this->categoryToList($category, ee()->TMPL->tagdata, $customFieldsEnabled, $prefix);
614:             }
615: 
616:             $output .= '</ul>';
617:         } else {
618:             $variables = array();
619: 
620:             $this->categoryCollectionToVariables($categories, $variables, $customFieldsEnabled, $prefix);
621: 
622:             $output = ee()->TMPL->parse_variables(ee()->TMPL->tagdata, $variables);
623: 
624:             if ($backspace = ee()->TMPL->fetch_param('backspace')) {
625:                 $output = substr($output, 0, -$backspace);
626:             }
627:         }
628: 
629:         return $output;
630: 
631:     }
632: 
633:     /**
634:      * Convert a Category collection into a multi-dimensional array suitable for ee()->TMPL->parse_variables
635:      *
636:      * @param  CategoryCollection $categories
637:      * @param  array              $variables
638:      * @param  boolean            $customFieldsEnabled
639:      * @param  string             $prefix
640:      * @return void
641:      */
642:     protected function categoryCollectionToVariables(CategoryCollection $categories, array &$variables, $customFieldsEnabled = false, $prefix = '')
643:     {
644:         foreach ($categories as $category) {
645:             $variables[] = $this->categoryToVariables($category, $customFieldsEnabled, $prefix);
646: 
647:             if ($category->hasChildren()) {
648:                 $this->categoryCollectionToVariables($category->children, $variables, $customFieldsEnabled, $prefix);
649:             }
650:         }
651:     }
652: 
653:     /**
654:      * Convert a Category model into an array suitable for ee()->TMPL->parse_variables_row
655:      *
656:      * @param  Category $category
657:      * @param  boolean  $customFieldsEnabled
658:      * @param  string   $prefix
659:      * @return array
660:      */
661:     protected function categoryToVariables(Category $category, $customFieldsEnabled = false, $prefix = '')
662:     {
663:         $categoryUri = ee()->config->item('use_category_name') === 'y'
664:             ? '/'.ee()->config->item('reserved_category_word').'/'.$category->cat_url_title
665:             : '/C'.$category->cat_id;
666: 
667:         $regex = '#'.preg_quote($categoryUri).'(\/|\/P\d+\/?)?$#';
668: 
669:         $row = array(
670:             $prefix.'active' => (bool) preg_match($regex, ee()->uri->uri_string()),
671:             $prefix.'category_description' => $category->cat_description,
672:             $prefix.'category_id' => $category->cat_id,
673:             $prefix.'parent_id' => $category->parent_id,
674:             $prefix.'category_image' => $category->cat_image,
675:             $prefix.'category_name' => $category->cat_name,
676:             $prefix.'category_url_title' => $category->cat_url_title,
677:             $prefix.'path' => array($categoryUri, array('path_variable' => true)),
678:         );
679: 
680:         if ($customFieldsEnabled) {
681:             foreach ($category->getFields() as $field) {
682:                 $row[$prefix.$field->field_name] = $category->{$field->field_name};
683:             }
684:         }
685: 
686:         return $row;
687:     }
688: 
689:     /**
690:      * Convert a Category model into a list element
691:      *
692:      * @param  Category $category
693:      * @param  [type]   $tagdata
694:      * @param  boolean  $customFieldsEnabled
695:      * @param  string   $prefix
696:      * @return string
697:      */
698:     protected function categoryToList(Category $category, $tagdata, $customFieldsEnabled = false, $prefix = '')
699:     {
700:         $output = '<li>';
701: 
702:         $output .= ee()->TMPL->parse_variables_row($tagdata, $this->categoryToVariables($category, $customFieldsEnabled, $prefix));
703: 
704:         if ($category->hasChildren()) {
705:             $output .= ' <ul>';
706: 
707:             foreach ($category->children as $child) {
708:                 $output .= $this->categoryToList($child, $tagdata, $customFieldsEnabled, $prefix);
709:             }
710: 
711:             $output .= '</ul>';
712:         }
713: 
714:         $output .= '</li>';
715: 
716:         return $output;
717:     }
718: }
719: 
API documentation generated by ApiGen 2.8.0