/** * This method navigates thru the tree structure and validates the article content. * * @param InstantArticle $article The article that will be checked. * @return array of string with the warnings raised during the check. */ public static function check($article) { Type::enforce($article, InstantArticle::getClassName()); $warnings = array(); self::getReport(array($article), $warnings); return $warnings; }
public function get($node) { Type::enforce($node, 'DOMNode'); $elements = self::findAll($node, $this->selector); if (!empty($elements) && $elements->item(0)) { $element = $elements->item(0); do { $element = $element->nextSibling; } while ($element !== null && !Type::is($element, 'DOMElement')); if ($element && Type::is($element, 'DOMElement')) { if ($this->siblingSelector) { $siblings = self::findAll($element, $this->siblingSelector); if (!empty($siblings) && $siblings->item(0)) { $siblingElement = $siblings->item(0); } else { // Returns null because sibling content doesn't match return null; } } else { $siblingElement = $element; } Transformer::markAsProcessed($siblingElement); return Transformer::cloneNode($siblingElement); } } return null; }
public function apply($transformer, $context_element, $node) { $h2 = H2::create(); if (Type::is($context_element, array(Header::getClassName(), Caption::getClassName()))) { $context_element->withSubTitle($h2); } elseif (Type::is($context_element, InstantArticle::getClassName())) { $context_element->addChild($h2); } if ($this->getProperty(Caption::POSITION_BELOW, $node)) { $h2->withPosition(Caption::POSITION_BELOW); } if ($this->getProperty(Caption::POSITION_CENTER, $node)) { $h2->withPosition(Caption::POSITION_CENTER); } if ($this->getProperty(Caption::POSITION_ABOVE, $node)) { $h2->withPosition(Caption::POSITION_ABOVE); } if ($this->getProperty(Caption::ALIGN_LEFT, $node)) { $h2->withTextAlignment(Caption::ALIGN_LEFT); } if ($this->getProperty(Caption::ALIGN_CENTER, $node)) { $h2->withTextAlignment(Caption::ALIGN_CENTER); } if ($this->getProperty(Caption::ALIGN_RIGHT, $node)) { $h2->withTextAlignment(Caption::ALIGN_RIGHT); } $transformer->transform($h2, $node); return $context_element; }
public function apply($transformer, $instant_article, $node) { // Builds the slideshow $slideshow = Slideshow::create(); $instant_article->addChild($slideshow); $gallery = $this->getProperty(self::PROPERTY_JETPACK_DATA_GALLERY, $node); if ($gallery && isset($gallery)) { foreach ($gallery as $gallery_image) { // Constructs Image if it contains URL if (!Type::isTextEmpty($gallery_image['src'])) { $image = Image::create(); $image->withURL($gallery_image['src']); // Constructs Caption element when present in the JSON if (!Type::isTextEmpty($gallery_image['caption'])) { $caption = Caption::create(); $caption->appendText($gallery_image['caption']); $image->withCaption($caption); } $slideshow->addImage($image); } } } $transformer->transform($slideshow, $node); return $instant_article; }
/** * Returns the set of pages and their associated tokens based on a * short-lived user access token. * * @param AccessToken $accessToken A short-lived user access token. * * @return array * * @throws FacebookSDKException */ public function getPagesAndTokens($accessToken) { Type::enforce($accessToken, 'Facebook\\Authentication\\AccessToken'); // If we don't have a long-lived user token, exchange for one if (!$accessToken->isLongLived()) { try { // The OAuth 2.0 client handler helps us manage access tokens $OAuth2Client = $this->facebook->getOAuth2Client(); $accessToken = $OAuth2Client->getLongLivedAccessToken($accessToken); } catch (FacebookResponseException $e) { throw new FacebookSDKException("Failed to exchange short-lived access token for long-lived access token."); } } // Set this access token as the default $this->facebook->setDefaultAccessToken($accessToken); // Request the list of pages and associated page tokens that are // connected to this user try { $response = $this->facebook->get('/me/accounts?fields=name,id,access_token,supports_instant_articles,picture'); } catch (FacebookResponseException $e) { throw new FacebookSDKException('Graph API returned an error: ' . $e->getMessage()); } // Return the array of page objects for this user return $response->getGraphEdge(); }
/** * Appends unescaped HTML to a element using the right strategy. * * @param \DOMNode $element - The element to append the HTML to. * @param \DOMNode $content - The unescaped HTML to append. */ protected function dangerouslyAppendUnescapedHTML($element, $content) { Type::enforce($content, 'DOMNode'); Type::enforce($element, 'DOMNode'); $imported = $element->ownerDocument->importNode($content, true); $element->appendChild($imported); }
public function apply($transformer, $header, $node) { $page_url = $this->getProperty(self::PROPERTY_SPONSOR_PAGE_URL, $node); if ($page_url && !Type::isTextEmpty($page_url)) { $sponsor = Sponsor::create(); $header->withSponsor($sponsor); $sponsor->withPageUrl($page_url); } return $header; }
/** * Sets the attribution string * * @param string|Cite $attribution The attribution text * * @return $this */ public function withAttribution($attribution) { Type::enforce($attribution, [Type::STRING, Cite::getClassName()]); if (Type::is($attribution, Type::STRING)) { $this->attribution = Cite::create()->appendText($attribution); } else { $this->attribution = $attribution; } return $this; }
/** * Creates a message from a level string, using INFO if a invalid level string is provided. * * @param string $level the level string, case insensitive. * @param string $message the message from the server * * @return ServerMessage the message with the proper level */ public static function fromLevel($level, $message) { $level = strtolower($level); $validLevel = Type::isWithin($level, [self::FATAL, self::ERROR, self::WARNING, self::INFO]); if ($validLevel) { return new self($level, $message); } else { \Logger::getLogger('facebook-instantarticles-client')->info('Unknown message level "$level". Are you using the last SDK version?'); return new self(self::INFO, $message); } }
public function matchesNode($node) { // Only matches DOMElements (ignore text and comments) if (!Type::is($node, 'DOMElement')) { return false; } // Handles selector = tag if ($node->nodeName === $this->selector) { return true; } // Handles selector = .class if (preg_match('/^\\.[a-zA-Z][a-zA-Z0-9-]*$/', $this->selector) === 1) { // Tries every class $classNames = explode(' ', $node->getAttribute('class')); foreach ($classNames as $className) { if ('.' . $className === $this->selector) { return true; } } // No match! return false; } // Handles selector = tag.class if (preg_match('/^[a-zA-Z][a-zA-Z0-9-]*(\\.[a-zA-Z][a-zA-Z0-9-]*)?$/', $this->selector) === 1) { // Tries every class $classNames = explode(' ', $node->getAttribute('class')); foreach ($classNames as $className) { if ($node->nodeName . '.' . $className === $this->selector) { return true; } } // No match! return false; } // Proceed with the more expensive XPath query $document = $node->ownerDocument; $domXPath = new \DOMXPath($document); if (substr($this->selector, 0, 1) === '/') { $xpath = $this->selector; } else { $converter = new CssSelectorConverter(); $xpath = $converter->toXPath($this->selector); } $results = $domXPath->query($xpath); if (false !== $results) { foreach ($results as $result) { if ($result === $node) { return true; } } } return false; }
public function get($node) { Type::enforce($node, 'DOMNode'); $elements = self::findAll($node, $this->selector); if (!empty($elements) && $elements->item(0)) { if (!$this->attribute) { return true; } return $elements->item(0)->hasAttribute($this->attribute); } return false; }
public function get($node) { Type::enforce($node, 'DOMNode'); $elements = self::findAll($node, $this->selector); if (!empty($elements) && $elements->item(0)) { $element = $elements->item(0); if ($this->attribute) { return $element->getAttribute($this->attribute); } return $element->textContent; } return null; }
public function get($node) { Type::enforce($node, 'DOMNode'); $domXPath = new \DOMXPath($node->ownerDocument); $elements = $domXPath->query($this->selector, $node); if (!empty($elements) && $elements->item(0)) { $element = $elements->item(0); if ($this->attribute) { return $element->getAttribute($this->attribute); } return $element->textContent; } return null; }
private function formatWarningMessage() { $object = Type::stringify($this->element); if (!$this->configuration) { $this->configuration = parse_ini_file("validator_warning_messages.ini", true); } $simple_class_name = substr(strrchr($this->element->getClassName(), '\\'), 1); if (!isset($this->configuration['warning_messages'][$simple_class_name])) { $message = 'Invalid content on the object.'; } else { $message = $this->configuration['warning_messages'][$simple_class_name]; } return $message; }
public function apply($transformer, $context, $node) { $interactive = Interactive::create(); if (Type::is($context, InstantArticle::getClassName())) { $instant_article = $context; } elseif ($transformer->getInstantArticle()) { $instant_article = $transformer->getInstantArticle(); $context->disableEmptyValidation(); $context = Paragraph::create(); $context->disableEmptyValidation(); } else { $transformer->addWarning(new NoRootInstantArticleFoundWarning(null, $node)); return $context; } // Builds the interactive $iframe = $this->getProperty(self::PROPERTY_IFRAME, $node); $url = $this->getProperty(self::PROPERTY_URL, $node); if ($iframe) { $interactive->withHTML($iframe); } if ($url) { $interactive->withSource($url); } if ($iframe || $url) { $instant_article->addChild($interactive); if ($instant_article !== $context) { $instant_article->addChild($context); } } else { $transformer->addWarning(new InvalidSelector(self::PROPERTY_IFRAME, $instant_article, $node, $this)); } if ($this->getProperty(self::PROPERTY_WIDTH_COLUMN_WIDTH, $node)) { $interactive->withMargin(Interactive::COLUMN_WIDTH); } else { $interactive->withMargin(Interactive::NO_MARGIN); } $width = $this->getProperty(self::PROPERTY_WIDTH, $node); if ($width) { $interactive->withWidth($width); } $height = $this->getProperty(self::PROPERTY_HEIGHT, $node); if ($height) { $interactive->withHeight($height); } $suppress_warnings = $transformer->suppress_warnings; $transformer->suppress_warnings = true; $transformer->transform($interactive, $node); $transformer->suppress_warnings = $suppress_warnings; return $context; }
public function get($node) { $fragment = $node->ownerDocument->createDocumentFragment(); foreach ($this->children as $child) { $cloned_node = $child->get($node); if (Type::is($cloned_node, 'DOMNode')) { $fragment->appendChild($cloned_node); } } if ($fragment->hasChildNodes()) { return $fragment; } return null; }
public function apply($transformer, $context, $node) { $image = Image::create(); if (Type::is($context, InstantArticle::getClassName())) { $instant_article = $context; } elseif ($transformer->getInstantArticle()) { $instant_article = $transformer->getInstantArticle(); $context->disableEmptyValidation(); $context = Paragraph::create(); $context->disableEmptyValidation(); } else { $transformer->addWarning(new NoRootInstantArticleFoundWarning(null, $node)); return $context; } // Builds the image $url = $this->getProperty(self::PROPERTY_IMAGE_URL, $node); if ($url) { $image->withURL($url); $instant_article->addChild($image); if ($instant_article !== $context) { $instant_article->addChild($context); } } else { $transformer->addWarning(new InvalidSelector(self::PROPERTY_IMAGE_URL, $instant_article, $node, $this)); } if ($this->getProperty(Image::ASPECT_FIT, $node)) { $image->withPresentation(Image::ASPECT_FIT); } elseif ($this->getProperty(Image::ASPECT_FIT_ONLY, $node)) { $image->withPresentation(Image::ASPECT_FIT_ONLY); } elseif ($this->getProperty(Image::FULLSCREEN, $node)) { $image->withPresentation(Image::FULLSCREEN); } elseif ($this->getProperty(Image::NON_INTERACTIVE, $node)) { $image->withPresentation(Image::NON_INTERACTIVE); } if ($this->getProperty(self::PROPERTY_LIKE, $node)) { $image->enableLike(); } if ($this->getProperty(self::PROPERTY_COMMENTS, $node)) { $image->enableComments(); } $suppress_warnings = $transformer->suppress_warnings; $transformer->suppress_warnings = true; $transformer->transform($image, $node); $transformer->suppress_warnings = $suppress_warnings; return $context; }
/** * @param string|DOMDocument $document The document html of an Instant Article * * @return InstantArticle filled element that was parsed from the DOMDocument parameter */ public function parse($content) { if (Type::is($content, Type::STRING)) { libxml_use_internal_errors(true); $document = new \DOMDocument(); $document->loadHTML($content); libxml_use_internal_errors(false); } else { $document = $content; } $json_file = file_get_contents(__DIR__ . '/instant-articles-rules.json'); $instant_article = InstantArticle::create(); $transformer = new Transformer(); $transformer->loadRules($json_file); $transformer->transform($instant_article, $document); return $instant_article; }
public function get($node) { $content = null; Type::enforce($node, 'DOMNode'); $elements = self::findAll($node, $this->selector); if (!empty($elements) && $elements->item(0)) { $element = $elements->item(0); if ($this->attribute) { $content = $element->getAttribute($this->attribute); } else { $content = $element->textContent; } } if (!Type::isTextEmpty($content)) { return json_decode($content, true); } return null; }
public function pages() { if (get_option('instant_articles_app_user_access_token')) { $userAccessToken = new AccessToken(get_option('instant_articles_app_user_access_token')); Type::enforce($userAccessToken, 'Facebook\\Authentication\\AccessToken'); $helper = Helper::create(get_option('instant_articles_app_id'), get_option('instant_articles_app_secret')); try { $helper->getPagesAndTokens($userAccessToken)->all(); } catch (Facebook\Exceptions\FacebookResponseException $e) { print_r($e); die; } // Grab pages you are admin of and tokens $pages_data = $helper->getPagesAndTokens($userAccessToken)->all(); //print_r($pages_data);die; return $pages_data; } else { return false; } }
/** * @return string */ public function __toString() { $reflection = new \ReflectionClass(get_class($this->context)); $className = $reflection->getShortName(); $nodeName = $this->node->nodeName; if (substr($nodeName, 0, 1) === '#') { $nodeDescription = '"' . mb_strimwidth($this->node->textContent, 0, 30, '...') . '"'; } else { $nodeDescription = '<'; $nodeDescription .= $nodeName; if (Type::is($this->node, 'DOMElement')) { $class = $this->node->getAttribute('class'); if ($class) { $nodeDescription .= ' class="' . $class . '"'; } } $nodeDescription .= '>'; } return "No rules defined for {$nodeDescription} in the context of {$className}"; }
/** * @param string $fragment * * @return $this */ public function withFragment($fragment) { Type::enforce($fragment, Type::STRING); $this->fragment = $fragment; return $this; }
/** * The Text position that will be used. * * @see Caption::POSITION_ABOVE * @see Caption::POSITION_BELOW * @see Caption::POSITION_CENTER * * @param string $position that will be used. * @return $this */ public function withPosition($position) { Type::enforceWithin($position, [Caption::POSITION_ABOVE, Caption::POSITION_BELOW, Caption::POSITION_CENTER]); $this->position = $position; return $this; }
/** * Overrides the Element::isValid(). * * @see Element::isValid(). * @return true for valid GeoTag that contains not empty script, false otherwise. */ public function isValid() { return !Type::isTextEmpty($this->script); }
/** * @param string $selector * * @return $this */ public function withSelector($selector) { Type::enforce($selector, Type::STRING); $this->selector = $selector; return $this; }
public function testStringEmpty() { $this->assertTrue(Type::isTextEmpty("")); $this->assertTrue(Type::isTextEmpty(" ")); $this->assertTrue(Type::isTextEmpty("\t\t")); $this->assertTrue(Type::isTextEmpty(" ")); $this->assertTrue(Type::isTextEmpty("\n")); }
public function get($node) { Type::enforce($node, 'DOMNode'); $elements = self::findAll($node, $this->selector); if (!empty($elements) && $elements->item(0)) { $element = $elements->item(0); if ($this->attribute) { $result = $element->getAttribute($this->attribute); } else { $result = $element->textContent; } if (!Type::isTextEmpty($this->prefix)) { $result = $this->prefix . $result; } if (!Type::isTextEmpty($this->suffix)) { $result = $result . $this->suffix; } return $result; } return null; }
/** * Sets all items of the list as the array on the parameter * * @param string|[]ListItem[] $new_items The new items. Replaces all items from the list * * @return $this */ public function withItems($new_items) { Type::enforceArrayOf($new_items, [ListItem::getClassName(), Type::STRING]); $this->items = []; foreach ($new_items as $new_item) { $this->addItem($new_item); } return $this; }
/** * Overrides the Element::isValid(). * * @see Element::isValid(). * @return true for valid Author that contains not empty name, false otherwise. */ public function isValid() { return !Type::isTextEmpty($this->name); }
/** * Get the submission status of an Instant Article. * * @param string|null $submissionStatusID the submission status ID * @return InstantArticleStatus */ public function getSubmissionStatus($submissionStatusID) { if (!$submissionStatusID) { return InstantArticleStatus::notFound(); } Type::enforce($submissionStatusID, Type::STRING); $response = $this->facebook->get($submissionStatusID . '?fields=status,errors'); $articleStatus = $response->getGraphNode(); $messages = []; $errors = $articleStatus->getField('errors'); if (null !== $errors) { foreach ($errors as $error) { $messages[] = ServerMessage::fromLevel($error['level'], $error['message']); } } return InstantArticleStatus::fromStatus($articleStatus->getField('status'), $messages); }