/** * Generate article.json contents. It does so by looping though all data, * generating valid JSON and adding attachments to workspace/tmp directory. * * @return string The generated JSON for article.json * @access private */ private function generate_json() { // Base JSON $json = array('version' => '1.1', 'identifier' => 'post-' . $this->content_id(), 'language' => 'en', 'title' => $this->content_title()); // Builders $json['documentStyle'] = $this->build_article_style(); foreach ($this->builders as $name => $builder) { $arr = $builder->to_array(); if ($arr) { $json[$name] = $arr; } } $json = apply_filters('apple_news_generate_json', $json, $this->content_id()); $json = json_encode($json); // Check the JSON for unicode errors. // For now, we'll assume that multiple unicode characters in sequence // containing the  (\u00C2) indicate a problem as that has been the // most common indication of the issue. preg_match_all('/(\\\\u[0-9a-fA-F]{4}){2,}/', $json, $matches); if (!empty($matches[0])) { // Get a unique list of character sequences $character_sequences = array_unique($matches[0]); foreach ($character_sequences as &$sequence) { // Convert back to a display format $sequence = json_decode('{ "value":"' . $sequence . '"}'); $sequence = $sequence->value; } $this->workspace->log_error('json_errors', sprintf(__('Invalid unicode character sequences were found that could cause display issues on Apple News: %s', 'apple-news'), implode(', ', $character_sequences))); } return $json; }
/** * Given a node, returns an array of all the components inside that node. If * the node is a component itself, returns an array of only one element. * * @param DomNode $node * @return array * @static * @access public */ public static function get_components_from_node($node) { $result = array(); foreach (self::$components as $shortname => $class) { $matched_node = $class::node_matches($node); // Nothing matched? Skip to next match. if (!$matched_node) { continue; } // Did we match several components? If so, a hash is returned. Both the // body and heading components can returns this, in the case they find // non-markdown-able elements inside. if (is_array($matched_node)) { foreach ($matched_node as $base_component) { $result[] = self::get_component($base_component['name'], $base_component['value']); } return $result; } // We matched a single node $html = $node->ownerDocument->saveXML($matched_node); $result[] = self::get_component($shortname, $html); return $result; } // Nothing found. Maybe it's a container element? if ($node->hasChildNodes()) { foreach ($node->childNodes as $child) { $result = array_merge($result, self::get_components_from_node($child, $node)); } // Remove all nulls from the array $result = array_filter($result); } // If nothing was found, log this as a component error by recording the node name. // Only record components with a tagName since otherwise there is nothing to report. // Others nodes without a match are almost always just stray empty text nodes // that are always safe to remove. Paragraphs should also be ignored for this reason. if (empty($result) && (!empty($node->tagName) && 'p' !== $node->tagName)) { self::$workspace->log_error('component_errors', $node->tagName); } return $result; }