This commit is contained in:
2026-05-05 20:31:55 +02:00
parent 0776c4531e
commit d203370870
9 changed files with 682 additions and 42 deletions

View File

@@ -1,6 +1,118 @@
<?php
class Cron
{
private static function getDfsRecentPositions( $phrase_id, $limit = 5 )
{
global $mdb;
return $mdb -> select( 'pro_rr_phrases_positions', [ 'position', 'date' ], [
'AND' => [
'phrase_id' => $phrase_id,
'position[!]' => null
],
'ORDER' => [ 'date' => 'DESC' ],
'LIMIT' => $limit
] );
}
private static function getDfsPositionVolatility( $positions )
{
if ( !is_array( $positions ) or count( $positions ) < 2 )
return 'short';
$max_delta = 0;
$last = null;
foreach ( $positions as $position )
{
$current = (int)$position['position'];
if ( $current == 0 )
return 'volatile';
if ( $last !== null )
$max_delta = max( $max_delta, abs( $last - $current ) );
$last = $current;
}
if ( $max_delta > 5 )
return 'volatile';
if ( $max_delta > 1 )
return 'mild';
return 'stable';
}
private static function getDfsAdaptiveIntervalDays( $row, $positions )
{
$volatility = self::getDfsPositionVolatility( $positions );
if ( !is_array( $positions ) or count( $positions ) < 3 )
return 1;
if ( $volatility == 'volatile' )
return 1;
if ( $volatility == 'mild' )
return 2;
if ( count( $positions ) >= 5 )
{
$last_position = (int)$positions[0]['position'];
if ( $last_position > 0 and $last_position <= 10 )
return 3;
if ( $last_position > 10 and $last_position <= 50 )
return 5;
}
return 1;
}
private static function getDfsDepth( $last_position, $positions )
{
$last_position = (int)$last_position;
$volatility = self::getDfsPositionVolatility( $positions );
if ( !$last_position )
return 50;
if ( $last_position <= 10 )
return $volatility == 'stable' ? 10 : 20;
if ( $last_position <= 20 )
return $volatility == 'stable' ? 20 : 30;
return 50;
}
private static function isDfsPhraseDue( $row, $positions )
{
if ( $row['last_checked'] == '2012-01-01' or !$row['last_checked'] )
return true;
if ( date( 'Y-m-d', strtotime( $row['last_checked'] ) ) == date( 'Y-m-d' ) )
return false;
if ( $row['days_offset'] and (int)$row['days_offset'] > 0 )
$interval_days = (int)$row['days_offset'];
else
$interval_days = self::getDfsAdaptiveIntervalDays( $row, $positions );
return date( 'Y-m-d', strtotime( '+' . $interval_days . ' days', strtotime( $row['last_checked'] ) ) ) <= date( 'Y-m-d' );
}
private static function getDfsIntervalLabel( $row, $positions )
{
if ( $row['days_offset'] and (int)$row['days_offset'] > 0 )
return 'manual:' . (int)$row['days_offset'] . 'd';
return 'auto:' . self::getDfsAdaptiveIntervalDays( $row, $positions ) . 'd';
}
public static function fill_missing_positions()
{
global $mdb;
@@ -161,7 +273,9 @@ class Cron
$result = $client->get('/v3/serp/google/organic/task_get/advanced/' . $row['ds_id'] );
if ( $result['status_code'] == '20000' )
{
$sites = $result['tasks'][0]['result'][0]['items'];
$sites = isset( $result['tasks'][0]['result'][0]['items'] ) ? $result['tasks'][0]['result'][0]['items'] : [];
$phrase_position = 0;
$site_url = '';
foreach ( $sites as $site )
{
@@ -201,13 +315,11 @@ class Cron
$mdb -> insert( 'phrase_positions_statistic', [
'phrase_id' => $row['id'],
'position' => $site['rank_group'],
'position' => (int)$phrase_position,
'date' => date( 'Y-m-d' )
] );
}
$phrase_position = $site['rank_group'];
$mdb -> update( 'pro_rr_phrases', [ 'last_checked' => date( 'Y-m-d' ), 'filled_missing_positions' => 0, 'ds_id' => null, 'ds_ready' => 0 ], [ 'id' => $row['id'] ] );
return [
@@ -227,48 +339,40 @@ class Cron
{
global $mdb;
$sql = 'SELECT * FROM ( '
. 'SELECT '
. 'prp.id, phrase, url, localization, last_checked, days_offset, prs.name '
. 'FROM '
. 'pro_rr_phrases AS prp, pro_rr_sites AS prs '
. 'WHERE '
. 'prs.id = prp.site_id '
. 'AND '
. 'last_checked != \'' . date( 'Y-m-d' ) . '\' '
. 'AND '
. '( prp.date_end >= \'' . date( 'Y-m-d' ) . '\' OR prp.date_end IS NULL ) '
. 'AND '
. '( prp.date_start <= \'' . date( 'Y-m-d' ) . '\' OR prp.date_start IS NULL ) '
. 'AND '
. '( prs.date_start <= \'' . date( 'Y-m-d' ) . '\' OR prs.date_start IS NULL ) '
. 'AND '
. '( prs.date_end >= \'' . date( 'Y-m-d' ) . '\' OR prs.date_end IS NULL ) '
. 'AND '
. 'ds_id IS NULL '
. ') AS q1 '
. 'WHERE '
. '( '
. 'days_offset IS NULL '
. 'OR '
. 'days_offset IS NOT NULL AND DATE( DATE_ADD( last_checked, INTERVAL +days_offset DAY ) ) <= CURRENT_DATE '
. ') OR last_checked = \'2012-01-01\' '
. 'ORDER BY '
. 'name ASC, phrase ASC '
. 'LIMIT 1';
$sql = 'SELECT '
. 'prp.id, phrase, url, localization, last_checked, days_offset, prs.name '
. 'FROM '
. 'pro_rr_phrases AS prp, pro_rr_sites AS prs '
. 'WHERE '
. 'prs.id = prp.site_id '
. 'AND '
. '( last_checked != \'' . date( 'Y-m-d' ) . '\' OR last_checked IS NULL ) '
. 'AND '
. '( prp.date_end >= \'' . date( 'Y-m-d' ) . '\' OR prp.date_end IS NULL ) '
. 'AND '
. '( prp.date_start <= \'' . date( 'Y-m-d' ) . '\' OR prp.date_start IS NULL ) '
. 'AND '
. '( prs.date_start <= \'' . date( 'Y-m-d' ) . '\' OR prs.date_start IS NULL ) '
. 'AND '
. '( prs.date_end >= \'' . date( 'Y-m-d' ) . '\' OR prs.date_end IS NULL ) '
. 'AND '
. 'ds_id IS NULL '
. 'ORDER BY '
. 'last_checked ASC, name ASC, phrase ASC '
. 'LIMIT 200';
$results = $mdb -> query( $sql ) -> fetchAll( \PDO::FETCH_ASSOC );
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
{
$positions = self::getDfsRecentPositions( $row['id'], 5 );
if ( !self::isDfsPhraseDue( $row, $positions ) )
continue;
$client = new RestClient( 'https://api.dataforseo.com/', null, 'pyziak84@gmail.com', '0p4rYWDNoK63eUUw' );
$last_position = $mdb -> get( 'pro_rr_phrases_positions', 'position', [ 'AND' => [ 'phrase_id' => $row['id'] ], 'ORDER' => [ 'date' => 'DESC' ] ] );
if ( $last_position <= 10 ) {
$depth = 30;
} elseif ( $last_position <= 30 ) {
$depth = 50;
} else {
$depth = 100;
}
$last_position = is_array( $positions ) and !empty( $positions ) ? (int)$positions[0]['position'] : 0;
$depth = self::getDfsDepth( $last_position, $positions );
$interval_label = self::getDfsIntervalLabel( $row, $positions );
if ( $row['localization'] and (int)$row['localization'] )
{
@@ -303,7 +407,7 @@ class Cron
return [
'status' => 'ok',
'msg' => 'Wysyłam do sprawdzenia frazę: <b>' . $row['phrase'] . '</b> - <b>' . $row['url'] . '</b> - (API 3.0) - ' . $task_post_result['tasks'][0]['id']
'msg' => 'Wysylam do sprawdzenia fraze: <b>' . $row['phrase'] . '</b> - <b>' . $row['url'] . '</b> - depth: <b>' . $depth . '</b>, interval: <b>' . $interval_label . '</b> - (API 3.0) - ' . $task_post_result['tasks'][0]['id']
];
}
}