/** * @testdox build() does not add the data-s9e-mediaembed attribute on XSL elements */ public function testSiteIdChoose() { $attributes = ['choose' => ['when' => ['test' => '@foo', 'iframe' => ['width' => '100', 'height' => '100', 'src' => 'foo']], 'otherwise' => ['flash' => ['width' => '200', 'height' => '200', 'src' => 'bar']]]]; $templateBuilder = new TemplateBuilder(); $template = $templateBuilder->build('foo', $attributes); $this->assertContains('<div data-s9e-mediaembed="foo"', $template); $this->assertNotRegexp('(<xsl:[^>]+data-s9e-mediaembed)', $template); }
/** * {@inheritdoc} */ protected function getContentTemplate() { $branches = isset($this->attributes['when'][0]) ? $this->attributes['when'] : [$this->attributes['when']]; $template = '<xsl:choose>'; foreach ($branches as $when) { $template .= '<xsl:when test="' . htmlspecialchars($when['test'], ENT_COMPAT, 'UTF-8') . '">' . $this->templateBuilder->getTemplate($when) . '</xsl:when>'; } $template .= '<xsl:otherwise>' . $this->templateBuilder->getTemplate($this->attributes['otherwise']) . '</xsl:otherwise></xsl:choose>'; return $template; }
/** * Add a media site * * @param string $siteId Site's ID * @param array $siteConfig Site's config * @return Tag Tag created for this site */ public function add($siteId, array $siteConfig = null) { // Normalize the site ID $siteId = $this->normalizeId($siteId); // If there's no value, look into the default site definitions if (!isset($siteConfig)) { $siteConfig = $this->defaultSites->get($siteId); } // Add this site to the list $this->collection[$siteId] = $siteConfig; // Create the tag for this site $tag = new Tag(); // This tag should not need to be closed, and shouldn't have any descendants $tag->rules->autoClose(); $tag->rules->ignoreTags(); // Store attributes' configuration, starting with a default "url" attribute to store the // original URL if applicable $attributes = ['url' => ['type' => 'url']]; // Process the "scrape" directives if (isset($siteConfig['scrape'])) { $attributes += $this->addScrapes($tag, $siteConfig['scrape']); } // Add each "extract" as an attribute preprocessor if (isset($siteConfig['extract'])) { foreach ((array) $siteConfig['extract'] as $regexp) { // Get the attributes filled by this regexp $attrRegexps = $tag->attributePreprocessors->add('url', $regexp)->getAttributes(); // For each named subpattern in the regexp, ensure that an attribute exists and // create it otherwise, using the subpattern as regexp filter foreach ($attrRegexps as $attrName => $attrRegexp) { $attributes[$attrName]['regexp'] = $attrRegexp; } } } // Overwrite attribute declarations if (isset($siteConfig['attributes'])) { foreach ($siteConfig['attributes'] as $attrName => $attrConfig) { foreach ($attrConfig as $configName => $configValue) { $attributes[$attrName][$configName] = $configValue; } } } // Create the attributes $hasRequiredAttribute = false; foreach ($attributes as $attrName => $attrConfig) { $attribute = $tag->attributes->add($attrName); if (isset($attrConfig['preFilter'])) { $this->appendFilter($attribute, $attrConfig['preFilter']); } // Add a filter depending on the attribute's type or regexp if (isset($attrConfig['type'])) { // If "type" is "url", get the "#url" filter $filter = $this->configurator->attributeFilters['#' . $attrConfig['type']]; $attribute->filterChain->append($filter); } elseif (isset($attrConfig['regexp'])) { $attribute->filterChain->append(new RegexpFilter($attrConfig['regexp'])); } if (isset($attrConfig['required'])) { $attribute->required = $attrConfig['required']; } else { // Non-id attributes are marked as optional $attribute->required = $attrName === 'id'; } if (isset($attrConfig['postFilter'])) { $this->appendFilter($attribute, $attrConfig['postFilter']); } if (isset($attrConfig['defaultValue'])) { $attribute->defaultValue = $attrConfig['defaultValue']; } $hasRequiredAttribute |= $attribute->required; } // If there is an attribute named "id" we'll append its regexp to the list of attribute // preprocessors in order to support both forms [site]<url>[/site] and [site]<id>[/site] if (isset($attributes['id']['regexp'])) { // Add a named capture around the whole match $attrRegexp = preg_replace('(\\^(.*)\\$)s', "^(?'id'\$1)\$", $attributes['id']['regexp']); $tag->attributePreprocessors->add('url', $attrRegexp); } // If the tag definition does not have a required attribute, we use a filter to invalidate // the tag at parsing time if it does not have a non-default attribute. In other words, if // no attribute value is extracted, the tag is invalidated if (!$hasRequiredAttribute) { $tag->filterChain->append([__NAMESPACE__ . '\\Parser', 'hasNonDefaultAttribute'])->setJS(file_get_contents(__DIR__ . '/Parser/hasNonDefaultAttribute.js')); } // Create a template for this media site based on the preferred rendering method $tag->template = $this->templateBuilder->build($siteId, $siteConfig) . $this->appendTemplate; // Normalize the tag's templates $this->configurator->templateNormalizer->normalizeTag($tag); // Check the tag's safety $this->configurator->templateChecker->checkTag($tag); // Now add the tag to the list $this->configurator->tags->add($siteId, $tag); // Create a BBCode for this site if applicable if ($this->createIndividualBBCodes) { $this->configurator->BBCodes->add($siteId, ['defaultAttribute' => 'url', 'contentAttributes' => ['url']]); } return $tag; }