HEX
Server: LiteSpeed
System: Linux eko108.isimtescil.net 4.18.0-477.21.1.lve.1.el8.x86_64 #1 SMP Tue Sep 5 23:08:35 UTC 2023 x86_64
User: uyarreklamcomtr (11202)
PHP: 7.4.33
Disabled: opcache_get_status
Upload Files
File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/LinkStatus.php.tar
uyarreklam.com.tr/httpdocs/wp-content/plugins/broken-link-checker-seo/app/Models/LinkStatus.php000064400000017775151543031340031651 0ustar00var/www/vhosts<?php
namespace AIOSEO\BrokenLinkChecker\Models;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AIOSEO\BrokenLinkChecker\Core\Database;

/**
 * The LinkStatus DB model class.
 *
 * @since 1.0.0
 */
class LinkStatus extends Model {
	/**
	 * The name of the table in the database, without the prefix.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	protected $table = 'aioseo_blc_link_status';

	/**
	 * Fields that should be numeric values.
	 *
	 * @since 1.0.0
	 *
	 * @var array
	 */
	protected $integerFields = [ 'id', 'broken', 'dismissed', 'scan_count', 'redirect_count', 'http_status_code' ];

	/**
	 * Fields that are nullable.
	 *
	 * @since 1.0.0
	 *
	 * @var array
	 */
	protected $nullFields = [ 'last_scan_date', 'final_url' ];

	/**
	 * Fields that should be boolean values.
	 *
	 * @since 1.0.0
	 *
	 * @var array
	 */
	protected $booleanFields = [
		'broken',
		'dismissed'
	];

	/**
	 * Fields that contain a JSON string.
	 *
	 * @since 1.0.0
	 *
	 * @var array
	 */
	protected $jsonFields = [ 'log' ];

	/**
	 * Returns the Link Status with the given ID.
	 *
	 * @since 1.0.0
	 *
	 * @param  int        $linkStatusId The Link Status ID.
	 * @return LinkStatus               The Link Status instance.
	 */
	public static function getById( $linkStatusId ) {
		return aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status' )
			->where( 'id', $linkStatusId )
			->run()
			->model( 'AIOSEO\\BrokenLinkChecker\\Models\\LinkStatus' );
	}

	/**
	 * Returns a list of Link Status rows with the given IDs.
	 *
	 * @since 1.1.0
	 *
	 * @param  array $linkStatusIds List of Link Status IDs.
	 * @return array                List of Link Status instances.
	 */
	public static function getByIds( $linkStatusIds ) {
		return aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status' )
			->whereIn( 'id', $linkStatusIds )
			->run()
			->models( 'AIOSEO\\BrokenLinkChecker\\Models\\LinkStatus' );
	}

	/**
	 * Returns the Link Status with the given URL.
	 *
	 * @since 1.0.0
	 *
	 * @param  string     $url The URL (unhashed!).
	 * @return LinkStatus      The Link Status instance.
	 */
	public static function getByUrl( $url ) {
		$hash = sha1( $url );

		$linkStatus = aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status' )
			->where( 'url_hash', $hash )
			->run()
			->model( 'AIOSEO\\BrokenLinkChecker\\Models\\LinkStatus' );

		if ( ! $linkStatus->exists() ) {
			// Updates to the plugin can cause hash mismatches. Let's do another attempt using the URL.
			// We do a join to improve performance since the URL isn't indexed.
			$hostname = wp_parse_url( $url, PHP_URL_HOST );
			$result   = aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status as abls' )
				->select( 'abls.id' )
				->join( 'aioseo_blc_links as abl', 'abls.id = abl.blc_link_status_id' )
				->where( 'abl.hostname', $hostname )
				->where( 'abls.url', $url )
				->groupBy( 'abls.id' )
				->limit( 1 )
				->run()
				->result();

			if ( ! empty( $result[0]->id ) ) {
				$linkStatus = self::getById( $result[0]->id );

				if ( $linkStatus->exists() ) {
					// Reset the URL hash to prevent future mismatches.
					$linkStatus->url_hash = $hash;
					$linkStatus->save();
				}
			}
		}

		return $linkStatus;
	}

	/**
	 * Returns all broken links for a given post ID.
	 *
	 * @since 1.2.0
	 *
	 * @param int    $postId The post ID.
	 * @return array         The list of broken links.
	 */
	public static function getBrokenByPostId( $postId ) {
		$query = aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status as als' )
			->join( 'aioseo_blc_links as al', 'als.id = al.blc_link_status_id' )
			->where( 'al.post_id', $postId )
			->where( 'als.broken', true )
			->where( 'als.dismissed', false );

		return $query->run()
			->result();
	}

	/**
	 * Returns link status row results based on the given arguments.
	 * This is basically a wrapper/query builder that we use to fetch all the data we need for the Broken Links Report.
	 *
	 * @since   1.0.0
	 * @version 1.1.0 Moved from Links model to Link Status model.
	 *
	 * @param  string $filter      The active filter.
	 * @param  int    $limit       The limit.
	 * @param  int    $offset      The offset.
	 * @param  string $whereClause The WHERE clause.
	 * @param  string $orderBy     The order by.
	 * @param  string $orderDir    The order direction.
	 * @return array               List of Link Status rows with related Link rows embedded.
	 */
	public static function rowQuery( $filter = 'all', $limit = 20, $offset = 0, $whereClause = '', $orderBy = '', $orderDir = 'DESC' ) {
		$query = self::baseQuery( $filter, $whereClause )
			->select( 'als.*, al.external' )
			->limit( $limit, $offset );

		if ( $orderBy && $orderDir ) {
			$query->orderBy( "$orderBy $orderDir" );
		} else {
			$query->orderBy( 'als.id DESC' );
		}

		$linkStatusRows = $query->run()
			->result();

		if ( empty( $linkStatusRows ) ) {
			return [];
		}

		$rowsWithData = [];
		foreach ( $linkStatusRows as $linkStatusRow ) {
			$linkStatusRow->totalLinks = Link::rowQueryCount( $linkStatusRow->id );
			if ( $linkStatusRow->totalLinks > 1 ) {
				$rowsWithData[] = $linkStatusRow;
				continue;
			}

			// If this link status has just one link, then we'll get it here.
			// Otherwise we'll get them when the links table loads.
			$linkRows            = Link::rowQuery( $linkStatusRow->id, 1 );
			$linkStatusRow->link = reset( $linkRows );
			$rowsWithData[]      = $linkStatusRow;
		}

		return $rowsWithData;
	}

	/**
	 * Returns link status row count based on the given arguments.
	 * This is basically a wrapper/query builder that we use to fetch all the counts we need for the Broken Links Report.
	 *
	 * @since   1.0.0
	 * @version 1.1.0 Moved from Links model to Link Status model.
	 *
	 * @param  string $filter      The active filter.
	 * @param  string $whereClause The WHERE clause.
	 * @return int                 The row count.
	 */
	public static function rowCountQuery( $filter = 'all', $whereClause = '' ) {
		$query = self::baseQuery( $filter, $whereClause );

		return $query->count();
	}

	/**
	 * Returns the base query for the rowQuery() and rowCountQuery() methods.
	 *
	 * @since   1.0.0
	 * @version 1.1.0 Moved from Links model to Link Status model.
	 *
	 * @param  string   $filter      The active filter.
	 * @param  string   $whereClause The WHERE clause.
	 * @return Database              The query.
	 */
	private static function baseQuery( $filter = 'all', $whereClause = '' ) {
		$includedPostTypes    = aioseoBrokenLinkChecker()->helpers->getIncludedPostTypes();
		$includedPostStatuses = aioseoBrokenLinkChecker()->helpers->getIncludedPostStatuses();
		$excludedPostIds      = aioseoBrokenLinkChecker()->helpers->getExcludedPostIds();
		$excludedDomains      = aioseoBrokenLinkChecker()->helpers->getExcludedDomains();

		$query = aioseoBrokenLinkChecker()->core->db->start( 'aioseo_blc_link_status as als' )
			->join( 'aioseo_blc_links as al', 'als.id = al.blc_link_status_id' )
			->join( 'posts as p', 'al.post_id = p.ID' )
			->groupBy( 'al.url' );

		if ( ! empty( $whereClause ) ) {
			$query->whereRaw( $whereClause );
		}

		if ( ! empty( $includedPostStatuses ) ) {
			$query->whereIn( 'p.post_status', $includedPostStatuses );
		}

		if ( ! empty( $includedPostTypes ) ) {
			$query->whereIn( 'p.post_type', $includedPostTypes );
		}

		if ( ! empty( $excludedPostIds ) ) {
			$query->whereNotIn( 'p.ID', $excludedPostIds );
		}

		if ( ! empty( $excludedDomains ) ) {
			$query->whereNotIn( 'al.hostname', $excludedDomains );
		}

		if ( ! empty( $filter ) ) {
			switch ( $filter ) {
				case 'broken':
					$query->where( 'als.broken', true );
					$query->where( 'als.dismissed', false );
					break;
				case 'redirects':
					$query->where( 'als.redirect_count >', 0 );
					$query->where( 'als.dismissed', false );
					break;
				case 'dismissed':
					$query->where( 'als.dismissed', true );
					break;
				case 'not-checked':
					$query->where( 'als.last_scan_date', null );
					break;
				case 'all':
				default:
					$query->where( 'als.dismissed', false );
					break;
			}
		}

		return $query;
	}
}uyarreklam.com.tr/httpdocs/wp-content/plugins/broken-link-checker-seo/app/LinkStatus/LinkStatus.php000064400000024347151543364560032535 0ustar00var/www/vhosts<?php
namespace AIOSEO\BrokenLinkChecker\LinkStatus;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use AIOSEO\BrokenLinkChecker\Models;

/**
 * Handles the Link Status scan.
 *
 * @since 1.0.0
 */
class LinkStatus {
	/**
	 * The base URL for the broken link checker server.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	private $baseUrl = 'https://check-links.aioseo.com/v1/';

	/**
	 * The action name of the scan.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public $actionName = 'aioseo_blc_link_status_scan';

	/**
	 * Data class instance.
	 *
	 * @since 1.1.0
	 *
	 * @var Data
	 */
	public $data = null;

	/**
	 * Class constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		$this->data = new Data();

		add_action( $this->actionName, [ $this, 'checkLinkStatuses' ], 11, 1 );
		if ( ! is_admin() ) {
			return;
		}

		add_action( 'init', [ $this, 'scheduleScan' ], 3003 );
	}

	/**
	 * Schedules the link status scan.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function scheduleScan() {
		if ( ! aioseoBrokenLinkChecker()->license->isActive() ) {
			return;
		}

		// If there is no action at all, schedule one.
		if ( ! aioseoBrokenLinkChecker()->actionScheduler->isScheduled( $this->actionName ) ) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleAsync( $this->actionName );
		}
	}

	/**
	 * Sends links to the server to check their status.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function checkLinkStatuses() {
		if ( ! aioseoBrokenLinkChecker()->license->isActive() ) {
			return;
		}

		$scanId = aioseoBrokenLinkChecker()->internalOptions->internal->scanId;
		if ( ! empty( $scanId ) ) {
			// If we have a scan ID, check if the results are ready.
			$this->checkForScanResults();

			return;
		}

		// If we don't have a scan ID, first check if there are links that need to be checked.
		$linksToCheck = $this->data->getlinksToCheck();
		if ( empty( $linksToCheck ) ) {
			// If there are no links to check, wait 15 minutes.
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, 15 * MINUTE_IN_SECONDS );

			return;
		}

		// If there are links to check, start a new scan.
		$this->startScan();
	}

	/**
	 * Start a scan and store the scan ID.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	private function startScan() {
		$requestBody = array_merge(
			$this->data->getBaseData(),
			[
				'links' => $this->data->getlinksToCheck()
			]
		);

		$response     = $this->doPostRequest( 'scan/start/', $requestBody );
		$responseCode = (int) wp_remote_retrieve_response_code( $response );

		if ( 401 === $responseCode ) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, DAY_IN_SECONDS + wp_rand( 60, 600 ) );

			return;
		}

		if ( 418 === $responseCode ) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, HOUR_IN_SECONDS + wp_rand( 60, 600 ) );

			return;
		}

		$responseBody = json_decode( wp_remote_retrieve_body( $response ) );
		if (
			is_wp_error( $response ) ||
			200 !== $responseCode ||
			empty( $responseBody->success ) ||
			empty( $responseBody->scanId ) ||
			! isset( $responseBody->quotaRemaining )
		) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, MINUTE_IN_SECONDS );

			return;
		}

		aioseoBrokenLinkChecker()->internalOptions->internal->scanId                  = $responseBody->scanId;
		aioseoBrokenLinkChecker()->internalOptions->internal->license->quotaRemaining = $responseBody->quotaRemaining;
		if ( aioseoBrokenLinkChecker()->internalOptions->internal->license->quota !== $responseBody->quota ) {
			// If the quota changed, reactivate the license to pull in the latest date from the marketing site.
			aioseoBrokenLinkChecker()->internalOptions->internal->license->quota = $responseBody->quota;
			aioseoBrokenLinkChecker()->license->activate();
		}

		aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, MINUTE_IN_SECONDS );
	}

	/**
	 * Checks if the scan has been completed. If so, parses and stores the results.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	private function checkForScanResults() {
		$scanId = aioseoBrokenLinkChecker()->internalOptions->internal->scanId;
		if ( empty( $scanId ) ) {
			return;
		}

		$response     = $this->doPostRequest( "scan/{$scanId}/" );
		$responseCode = (int) wp_remote_retrieve_response_code( $response );

		if ( 401 === $responseCode ) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, DAY_IN_SECONDS + wp_rand( 60, 600 ) );

			return;
		}

		if ( 418 === $responseCode ) {
			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, HOUR_IN_SECONDS + wp_rand( 60, 600 ) );

			return;
		}

		$responseBody = json_decode( wp_remote_retrieve_body( $response ) );
		if ( is_wp_error( $response ) && 200 !== $responseCode || empty( $responseBody->success ) ) {
			// If the scan data cannot be found on the server, wipe the scan ID so the scan restarts.
			if ( ! empty( $responseBody->error ) && 'missing-scan-data' === strtolower( $responseBody->error ) ) {
				aioseoBrokenLinkChecker()->internalOptions->internal->scanId = '';
			}

			aioseoBrokenLinkChecker()->actionScheduler->scheduleSingle( $this->actionName, MINUTE_IN_SECONDS );

			return;
		}

		$this->parseResults( $responseBody );

		aioseoBrokenLinkChecker()->internalOptions->internal->license->quotaRemaining = $responseBody->quotaRemaining;
		if ( aioseoBrokenLinkChecker()->internalOptions->internal->license->quota !== $responseBody->quota ) {
			// If the quota changed, reactivate the license to pull in the latest date from the marketing site.
			aioseoBrokenLinkChecker()->internalOptions->internal->license->quota = $responseBody->quota;
			aioseoBrokenLinkChecker()->license->activate();
		}

		// Once the request is successful, we know the scan has been completed and we can go ahead and reset it.
		$this->doDeleteRequest( "scan/{$scanId}/" );
		aioseoBrokenLinkChecker()->internalOptions->internal->scanId = '';
	}

	/**
	 * Parse the results that came back from the server.
	 *
	 * @since 1.0.0
	 *
	 * @param  Object $responseBody The response body object.
	 * @return void
	 */
	private function parseResults( $responseBody ) {
		$scanData = json_decode( $responseBody->scanData );
		if ( empty( $scanData ) || empty( $scanData->urls ) ) {
			return;
		}

		foreach ( $scanData->urls as $url ) {
			$this->parseResultsHelper( $url );
		}
	}

	/**
	 * Helper function for parseResults().
	 *
	 * @since 1.0.0
	 *
	 * @param  Object $url The URL object.
	 * @return void
	 */
	public function parseResultsHelper( $url ) {
		$linkStatus = Models\LinkStatus::getByUrl( $url->url );
		if ( ! $linkStatus->exists() || empty( $url->data ) ) {
			return;
		}

		if ( empty( $url->data->status ) ) {
			$linkStatus->scanning         = false;
			$linkStatus->broken           = true;
			$linkStatus->http_status_code = null;
			$linkStatus->request_duration = 0;
			$linkStatus->final_url        = '';
			$linkStatus->scan_count       = $linkStatus->scan_count + 1;
			$linkStatus->last_scan_date   = aioseoBrokenLinkChecker()->helpers->timeToMysql( time() );
			$linkStatus->log              = [
				'error'   => ! empty( $url->data->error ) ? $url->data->error : '',
				'headers' => ! empty( $url->data->headers ) ? $url->data->headers : ''
			];

			if ( ! $linkStatus->first_failure ) {
				$linkStatus->first_failure = aioseoBrokenLinkChecker()->helpers->timeToMysql( time() );
			}

			$linkStatus->save();

			return;
		}

		$success       = (int) $url->data->status < 400;
		$redirectCount = count( $url->data->redirects );
		$finalUrl      = $redirectCount ? $url->data->redirects[ $redirectCount - 1 ] : '';

		$linkStatus->scanning         = false;
		$linkStatus->broken           = ! $success;
		$linkStatus->http_status_code = (int) $url->data->status;
		$linkStatus->redirect_count   = $redirectCount;
		$linkStatus->final_url        = $finalUrl;
		$linkStatus->request_duration = ! empty( $url->data->stats->loadTime ) ? abs( $url->data->stats->loadTime ) : 0;
		$linkStatus->scan_count       = $linkStatus->scan_count + 1;
		$linkStatus->last_scan_date   = aioseoBrokenLinkChecker()->helpers->timeToMysql( time() );
		$linkStatus->log              = [
			'error'   => ! empty( $url->data->error ) ? $url->data->error : '',
			'headers' => ! empty( $url->data->headers ) ? $url->data->headers : ''
		];

		if ( $success ) {
			$linkStatus->last_success  = aioseoBrokenLinkChecker()->helpers->timeToMysql( time() );
			$linkStatus->first_failure = null;
		} elseif ( ! $linkStatus->first_failure ) {
			$linkStatus->first_failure = aioseoBrokenLinkChecker()->helpers->timeToMysql( time() );
		}

		$linkStatus->save();
	}

	/**
	 * Returns the URL for the Broken Link Checker server.
	 *
	 * @since 1.0.0
	 *
	 * @return string The URL.
	 */
	public function getUrl() {
		if ( defined( 'AIOSEO_BROKEN_LINK_CHECKER_SCAN_URL' ) ) {
			return AIOSEO_BROKEN_LINK_CHECKER_SCAN_URL;
		}

		return $this->baseUrl;
	}

	/**
	 * Sends a POST request to the server.
	 *
	 * @since 1.0.0
	 *
	 * @param  string          $path        The path.
	 * @param  array           $requestBody The request body.
	 * @return array|\WP_Error              The response or WP_Error on failure.
	 */
	public function doPostRequest( $path, $requestBody = [] ) {
		$requestData = [
			'headers' => [
				'X-AIOSEO-BLC-License' => aioseoBrokenLinkChecker()->internalOptions->internal->license->licenseKey,
				'Content-Type'         => 'application/json'
			],
			'timeout' => 60
		];

		if ( ! empty( $requestBody ) ) {
			$requestData['body'] = wp_json_encode( $requestBody );
		}

		$baseUrl  = $this->getUrl();
		$response = wp_remote_post( $baseUrl . $path, $requestData );

		return $response;
	}

	/**
	 * Sends a DELETE request to the server.
	 *
	 * @since 1.0.0
	 *
	 * @param  string          $path The path.
	 * @return array|\WP_Error       The response or WP_Error on failure.
	 */
	public function doDeleteRequest( $path ) {
		$requestData = [
			'method'  => 'DELETE',
			'headers' => [
				'X-AIOSEO-BLC-License' => aioseoBrokenLinkChecker()->internalOptions->internal->license->licenseKey,
				'Content-Type'         => 'application/json'
			],
			'timeout' => 60
		];

		$baseUrl  = $this->getUrl();
		$response = wp_remote_request( $baseUrl . $path, $requestData );

		return $response;
	}
}