class-gsc-issues.php 4.19 KB
Newer Older
imac's avatar
imac committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
<?php
/**
 * @package WPSEO\Admin|Google_Search_Console
 */

/**
 * Class WPSEO_GSC_Issues
 */
class WPSEO_GSC_Issues {

	/**
	 * @var string
	 */
	private $option_name = '';

	/**
	 * List of all current issues to compare with received issues
	 *
	 * @var array
	 */
	private $current_issues = array();

	/**
	 * Holder for all the issues
	 *
	 * @var array
	 */
	private $issues = array();

	/**
	 * Setting up the properties and fetching the current issues
	 *
	 * @param string     $platform       Platform type (desktop, mobile, feature phone).
	 * @param string     $category       Issues category.
	 * @param array|bool $fetched_issues Optional set of issues.
	 */
	public function __construct( $platform, $category, $fetched_issues = false ) {
		$this->option_name = strtolower( 'wpseo-gsc-issues-' . $platform . '-' . $category );
		$this->issues      = $this->get_issues();

		if ( ! empty( $fetched_issues ) && is_array( $fetched_issues ) ) {
			$this->save_fetched_issues( $fetched_issues );
		}
	}
	/**
	 * Getting the issues from the options.
	 *
	 * @return array
	 */
	public function get_issues() {
		return get_option( $this->option_name, array() );
	}

	/**
	 * Deleting the issue from the issues
	 *
	 * @param string $url URL to delete issues for.
	 *
	 * @return bool
	 */
	public function delete_issue( $url ) {
		$target_issue = $this->get_issue_by_url( $url );
		if ( $target_issue !== false ) {
			unset( $this->issues[ $target_issue ] );

			$this->save_issues( $this->issues );

			return true;
		}

		return false;
	}

	/**
	 * Fetching the issues for current category and compare them with the already existing issues.
	 *
	 * @param array $fetched_issues Set of retrieved issues.
	 */
	private function save_fetched_issues( array $fetched_issues ) {
		$this->set_current_issues();

		$crawl_issues = $this->get_issues();

		// Walk through the issues to do the comparison.
		foreach ( $fetched_issues as $issue ) {
			$this->issue_compare( $crawl_issues, $issue );
		}

		$this->save_issues( $crawl_issues );

		// Refresh the value of $this->issues.
		$this->issues = $this->get_issues();
	}

	/**
	 * Comparing the issue with the list of current existing issues
	 *
	 * @param array    $crawl_issues Set of issues by reference.
	 * @param stdClass $issue        Issue object to check against the list.
	 */
	private function issue_compare( &$crawl_issues, $issue ) {
		$issue->pageUrl = WPSEO_Utils::format_url( (string) $issue->pageUrl );

		if ( ! in_array( $issue->pageUrl, $this->current_issues ) ) {
			array_push(
				$crawl_issues,
				$this->get_issue( $this->create_issue( $issue ) )
			);
		}
	}

	/**
	 * The fetched issue from the API will be parsed as an WPSEO_Crawl_Issue object. After initializing the issue as an
	 * object, the object will be returned
	 *
	 * @param stdClass $issue Issue data object.
	 *
	 * @return WPSEO_GSC_Issue
	 */
	private function create_issue( $issue ) {
		return new WPSEO_GSC_Issue(
			$issue->pageUrl,
			new DateTime( (string) $issue->first_detected ),
			new DateTime( (string) $issue->last_crawled ),
			(string) ( ! empty( $issue->responseCode ) ) ? $issue->responseCode : null
		);
	}

	/**
	 * Returns the crawl issue as an array.
	 *
	 * @param WPSEO_GSC_Issue $crawl_issue Issue object instance.
	 *
	 * @return array()
	 */
	private function get_issue( WPSEO_GSC_Issue $crawl_issue ) {
		return $crawl_issue->to_array();
	}

	/**
	 * Saving the issues to the options. The target option is base on current platform and category.
	 *
	 * @param array $issues Set of issues.
	 */
	private function save_issues( array $issues ) {
		update_option( $this->option_name, $issues, false );
	}

	/**
	 * Getting the issues from the options and get only the URL out of it. This is because there will be a comparison
	 * with the issues from the API.
	 */
	private function set_current_issues() {
		if ( ! empty( $this->issues ) ) {
			$this->current_issues = wp_list_pluck( $this->issues, 'url' );
		}
	}

	/**
	 * Search in the issues for the given $url
	 *
	 * @param string $url Issue URL to search for.
	 *
	 * @return int|string
	 */
	private function get_issue_by_url( $url ) {
		foreach ( $this->issues as $key => $issue ) {
			if ( $url === $issue['url'] ) {
				return $key;
			}
		}

		return false;
	}
}