/**
  * Calculate the page analysis results for post.
  *
  * @todo [JRF => whomever] check whether the results of this method are always checked with is_wp_error()
  * @todo [JRF => whomever] check the usage of this method as it's quite intense/heavy, see if it's only
  * used when really necessary
  * @todo [JRF => whomever] see if we can get rid of the passing by reference of $results as it makes
  * the code obfuscated
  *
  * @param  object $post Post to calculate the results for.
  *
  * @return  array|WP_Error
  */
 function calculate_results($post)
 {
     $options = WPSEO_Options::get_all();
     if (!class_exists('DOMDocument')) {
         $result = new WP_Error('no-domdocument', sprintf(__("Your hosting environment does not support PHP's %sDocument Object Model%s.", 'wordpress-seo'), '<a href="http://php.net/manual/en/book.dom.php">', '</a>') . ' ' . __("To enjoy all the benefits of the page analysis feature, you'll need to (get your host to) install it.", 'wordpress-seo'));
         return $result;
     }
     if (!is_array($post) && !is_object($post)) {
         $result = new WP_Error('no-post', __('No post content to analyse.', 'wordpress-seo'));
         return $result;
     } elseif (self::get_value('focuskw', $post->ID) === '') {
         $result = new WP_Error('no-focuskw', sprintf(__('No focus keyword was set for this %s. If you do not set a focus keyword, no score can be calculated.', 'wordpress-seo'), $post->post_type));
         self::set_value('linkdex', 0, $post->ID);
         return $result;
     } elseif (apply_filters('wpseo_use_page_analysis', true) !== true) {
         $result = new WP_Error('page-analysis-disabled', sprintf(__('Page Analysis has been disabled.', 'wordpress-seo'), $post->post_type));
         return $result;
     }
     $results = array();
     $job = array();
     $sampleurl = $this->get_sample_permalink($post);
     $job['pageUrl'] = preg_replace('`%(?:post|page)name%`', $sampleurl[1], $sampleurl[0]);
     $job['pageSlug'] = urldecode($post->post_name);
     $job['keyword'] = self::get_value('focuskw');
     $job['keyword_folded'] = $this->strip_separators_and_fold($job['keyword']);
     $job['post_id'] = $post->ID;
     $job['post_type'] = $post->post_type;
     $dom = new domDocument();
     $dom->strictErrorChecking = false;
     $dom->preserveWhiteSpace = false;
     /**
      * Filter: 'wpseo_pre_analysis_post_content' - Make the post content filterable before calculating the page analysis
      *
      * @api string $post_content The post content
      *
      * @param object $post The post
      */
     $post_content = apply_filters('wpseo_pre_analysis_post_content', $post->post_content, $post);
     // Check if the post content is not empty
     if (!empty($post_content)) {
         @$dom->loadHTML($post_content);
     }
     unset($post_content);
     $xpath = new DOMXPath($dom);
     // Check if this focus keyword has been used already.
     $this->check_double_focus_keyword($job, $results);
     // Keyword
     $this->score_keyword($job['keyword'], $results);
     // Title
     $title = self::get_value('title');
     if ($title !== '') {
         $job['title'] = $title;
     } else {
         if (isset($options['title-' . $post->post_type]) && $options['title-' . $post->post_type] !== '') {
             $title_template = $options['title-' . $post->post_type];
         } else {
             $title_template = '%%title%% - %%sitename%%';
         }
         $job['title'] = wpseo_replace_vars($title_template, $post);
     }
     unset($title);
     $this->score_title($job, $results);
     // Meta description
     $description = '';
     $desc_meta = self::get_value('metadesc');
     if ($desc_meta !== '') {
         $description = $desc_meta;
     } elseif (isset($options['metadesc-' . $post->post_type]) && $options['metadesc-' . $post->post_type] !== '') {
         $description = wpseo_replace_vars($options['metadesc-' . $post->post_type], $post);
     }
     unset($desc_meta);
     self::$meta_length = apply_filters('wpseo_metadesc_length', self::$meta_length, $post);
     $this->score_description($job, $results, $description, self::$meta_length);
     unset($description);
     // Body
     $body = $this->get_body($post);
     $firstp = $this->get_first_paragraph($body);
     $this->score_body($job, $results, $body, $firstp);
     unset($firstp);
     // URL
     $this->score_url($job, $results);
     // Headings
     $headings = $this->get_headings($body);
     $this->score_headings($job, $results, $headings);
     unset($headings);
     // Images
     $imgs = array();
     $imgs['count'] = substr_count($body, '<img');
     $imgs = $this->get_images_alt_text($post->ID, $body, $imgs);
     // Check featured image
     if (function_exists('has_post_thumbnail') && has_post_thumbnail()) {
         $imgs['count'] += 1;
         if (empty($imgs['alts'])) {
             $imgs['alts'] = array();
         }
         $imgs['alts'][] = $this->strtolower_utf8(get_post_meta(get_post_thumbnail_id($post->ID), '_wp_attachment_image_alt', true));
     }
     $this->score_images_alt_text($job, $results, $imgs);
     unset($imgs);
     unset($body);
     // Anchors
     $anchors = $this->get_anchor_texts($xpath);
     $count = $this->get_anchor_count($xpath);
     $this->score_anchor_texts($job, $results, $anchors, $count);
     unset($anchors, $count, $dom);
     $results = apply_filters('wpseo_linkdex_results', $results, $job, $post);
     $this->aasort($results, 'val');
     $overall = 0;
     $overall_max = 0;
     foreach ($results as $result) {
         $overall += $result['val'];
         $overall_max += 9;
     }
     if ($overall < 1) {
         $overall = 1;
     }
     $score = wpseo_calc(wpseo_calc($overall, '/', $overall_max), '*', 100, true);
     if (!is_wp_error($score)) {
         self::set_value('linkdex', absint($score), $post->ID);
         $results['total'] = $score;
     }
     return $results;
 }