{ // Parse the context $ctx = $this->parseContext($argCtx); // Retrieve the template slug from the context $tSlug = $ctx['template']; // Render using the legacy system if legacy ctx arg is given or no template was specified and the legacy // system should be used as a fallback if ($ctx['legacy'] || (empty($tSlug) && $this->fallBackToLegacySystem())) { return $this->legacyTemplate->render($argCtx); } // Get the template model instance $model = $this->getTemplateModel($tSlug); // Merge the model options with the non-schema ctx args $options = array_merge( Normalize::toArray($model[static::TEMPLATE_OPTIONS_KEY]), Normalize::toArray($ctx[static::CTX_OPTIONS_KEY]) ); // Include the template slug in the context $options['template'] = $model['slug']; // Get the template type instance and render it $tTypeInst = $this->getTemplateType($model); $itemsCollection = ($ctx['items'] instanceof CollectionInterface) ? $ctx['items'] : $this->feedItemCollection; $rendered = $tTypeInst->render([ 'options' => $options, 'items' => $itemsCollection, ]); return $this->containerTemplate->render([ 'ctx' => base64_encode(json_encode($argCtx)), 'slug' => $model['slug'], 'template' => $rendered, ]); } /** * Parses the render context, normalizing it to an array and filtering it against the schema. * * @since 4.13 * * @param array|stdClass|Traversable $ctx The render context. * * @return array The parsed context. */ protected function parseContext($ctx) { try { $normCtx = Normalize::toArray($ctx); } catch (InvalidArgumentException $exception) { $normCtx = []; } // Parse the context, putting all non-schema data in an "options" key $schema = $this->getContextSchema(); $pCtx = $this->parseArgsWithSchema($normCtx, $schema, '/', static::CTX_OPTIONS_KEY); return $pCtx; } /** * Retrieves the standard WP RSS Aggregator template context schema. * * @see ParseArgsWithSchemaCapableTrait::parseArgsWithSchema() * * @since 4.13 * * @return array */ protected function getContextSchema() { return [ 'template' => [ 'default' => '', 'filter' => FILTER_SANITIZE_STRING, ], 'legacy' => [ 'default' => false, 'filter' => FILTER_VALIDATE_BOOLEAN, ], 'items' => [ 'default' => $this->feedItemCollection, 'filter' => function ($items) { if ($items instanceof CollectionInterface) { return $items; } throw new InvalidArgumentException(__('The "items" must be a collection instance', 'wprss')); }, ] ]; } /** * Retrieves the template model instance for a given post slug. * * @since 4.13 * * @param string $slug The slug name of the template post. * * @return DataSetInterface The model instance. */ protected function getTemplateModel($slug) { $model = null; // Get the template model instance if (!empty($slug)) { try { $model = $this->templateCollection[$slug]; } catch (Exception $exception) { // Include warning in log that the template with the given slug was not found $this->logger->warning( __('Template "{0}" does not exist or could not be loaded. The default template was used instead.'), [$slug] ); } } // If the slug is empty or failed to get the template if (empty($model)) { // Fetch the default template $builtInCollection = $this->templateCollection->filter(['type' => '__built_in']); $builtInCollection->rewind(); if ($builtInCollection->getCount() > 0) { $model = $builtInCollection->current(); } else { $model = [ 'id' => '0', 'name' => 'Fallback', 'slug' => 'wpra-fallback-template', 'type' => '__built_in', 'options' => [ 'limit' => 15, 'title_max_length' => 0, 'title_is_link' => true, 'pagination' => false, 'pagination_type' => 'default', 'source_enabled' => true, 'source_prefix' => __('Source:', 'wprss'), 'source_is_link' => true, 'author_enabled' => false, 'author_prefix' => __('By', 'wprss'), 'date_enabled' => true, 'date_prefix' => __('Published on:', 'wprss'), 'date_format' => 'Y-m-d', 'date_use_time_ago' => false, 'links_behavior' => 'blank', 'links_nofollow' => false, 'links_video_embed_page' => false, 'bullets_enabled' => true, 'bullet_type' => 'default', 'custom_css_classname' => '', ], ]; } if (is_array($model)) { $model = new ArrayDataSet($model); } } return $model; } /** * Retrieves the template type instance for a template model. * * @since 4.13 * * @param DataSetInterface $model The template model. * * @return FeedTemplateTypeInterface The template type instance. */ protected function getTemplateType(DataSetInterface $model) { $type = isset($model['type']) ? $model['type'] : ''; return isset($this->types[$type]) ? $this->types[$type] : $this->types['list']; } /** * Checks whether or not the master feeds template should fall back to the legacy rendering method when no * template is explicitly specified in the render context. * * @since 4.13 * * @return bool True to fall back to the legacy rendering system, false to use the default template. */ protected function fallBackToLegacySystem() { return apply_filters('wpra/templates/fallback_to_legacy_system', false); } }