/**
  * 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;
 }
Example #18
0
 /**
  * @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;
 }
Example #23
0
 /**
  * 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;
 }
Example #24
0
 /**
  * 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("&nbsp;"));
     $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;
 }
Example #29
0
 /**
  * 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);
 }
Example #30
0
 /**
  * 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);
 }