506 lines
19 KiB
PHP
506 lines
19 KiB
PHP
<?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;
|
|
|
|
$sites = $mdb -> select( 'pro_rr_sites', [ 'id', 'name' ], [ 'OR' => [ 'date_confirm' => date( 'Y-m-d' ), 'need_confirm' => 0 ] ] );
|
|
if ( is_array( $sites ) and !empty( $sites ) ) foreach ( $sites as $site )
|
|
{
|
|
$phrases = $mdb -> select( 'pro_rr_phrases', [ 'id', 'phrase' ], [ 'AND' => [ 'filled_missing_positions' => 0, 'site_id' => $site['id'] ], 'ORDER' => [ 'phrase' => 'ASC' ], 'LIMIT' => 1 ] );
|
|
if ( is_array( $phrases ) and !empty( $phrases ) ) foreach ( $phrases as $phrase )
|
|
{
|
|
$positions = $mdb -> select( 'pro_rr_phrases_positions', [ 'position', 'date' ], [ 'AND' => [ 'phrase_id' => $phrase['id'] ], 'ORDER' => [ 'date' => 'DESC' ], 'LIMIT' => 1 ] );
|
|
if ( is_array( $positions ) and !empty( $positions ) ) foreach ( $positions as $position )
|
|
{
|
|
$previous_position = $mdb -> get( 'pro_rr_phrases_positions', [ 'date', 'position', 'url', 'map' ], [ 'AND' => [ 'phrase_id' => $phrase['id'], 'date[!]' => $position[ 'date' ] ], 'ORDER' => [ 'date' => 'DESC' ] ] );
|
|
|
|
if ( $previous_position['position'] != 0 and $position['position'] != 0 )
|
|
$average_position = round( ( $position['position'] + $previous_position['position'] ) / 2, 0 );
|
|
else if ( $previous_position['position'] == 0 and $position['position'] != 0 )
|
|
$average_position = $position['position'];
|
|
else if ( $previous_position['position'] != 0 and $position['position'] == 0 )
|
|
$average_position = $previous_position['position'];
|
|
else
|
|
$average_position = 0;
|
|
|
|
$begin = new DateTime( date( 'Y-m-d', strtotime( '+1 days', strtotime( $previous_position['date'] ) ) ) );
|
|
$end = new DateTime( date( 'Y-m-d', strtotime( '-1 days', strtotime( $position['date'] ) ) ) );
|
|
|
|
for ( $i = $begin; $i <= $end; $i -> modify( '+1 day' ) )
|
|
{
|
|
if ( !$mdb -> count( 'pro_rr_phrases_positions', [ 'AND' => [ 'phrase_id' => $phrase['id'], 'date' => $i -> format( "Y-m-d" ) ] ] ) )
|
|
{
|
|
$mdb -> insert( 'pro_rr_phrases_positions', [
|
|
'position' => $average_position > 10 ? rand( $average_position - 1, $average_position + 1 ) : $average_position,
|
|
'phrase_id' => $phrase['id'],
|
|
'url' => $previous_position['url'],
|
|
'map' => $previous_position['map'],
|
|
'date' => $i -> format( "Y-m-d" )
|
|
] );
|
|
}
|
|
}
|
|
$mdb -> update( 'pro_rr_phrases', [ 'filled_missing_positions' => 1 ], [ 'id' => $phrase['id'] ] );
|
|
}
|
|
else
|
|
{
|
|
$mdb -> update( 'pro_rr_phrases', [ 'filled_missing_positions' => 1 ], [ 'id' => $phrase['id'] ] );
|
|
}
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Uzupełniam brakujące pozycje: <b>' . $site['name'] . '</b> - <b>' . $phrase['phrase'] . '</b>.'
|
|
];
|
|
}
|
|
}
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
|
|
static public function archive_empty()
|
|
{
|
|
global $mdb;
|
|
|
|
$results = $mdb -> query( 'SELECT * FROM archive_phrases_positions WHERE date < \'' . date( 'Y-m-d', strtotime( '-4 years', time() ) ) . '\' ORDER BY id ASC LIMIT 1' ) -> fetchAll();
|
|
if ( is_array( $results ) and !empty( $results ) )
|
|
{
|
|
foreach ( $results as $row )
|
|
{
|
|
$mdb -> delete( 'archive_phrases_positions', [ 'id' => $row['id'] ] );
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Usuwam stare pozycje fraz z archiwum | ID: <b>' . $row['id'] . '</b>, data: <b>' . $row['date'] . '</b>, URL: <b>' . $row['url'] . '</b>'
|
|
];
|
|
}
|
|
}
|
|
else
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
|
|
public static function archive_positions()
|
|
{
|
|
global $mdb;
|
|
|
|
$results = $mdb -> query( 'SELECT * FROM pro_rr_phrases_positions WHERE date LIKE \'' . date( 'Y-m', strtotime( '-2 years', time() ) ) . '%\' LIMIT 1' ) -> fetchAll();
|
|
if ( is_array( $results ) and !empty( $results ) )
|
|
{
|
|
foreach ( $results as $row )
|
|
{
|
|
$mdb -> insert( 'archive_phrases_positions', [
|
|
'phrase_id' => $row['phrase_id'],
|
|
'position' => $row['position'],
|
|
'url' => $row['url'],
|
|
'map' => $row['map'],
|
|
'date' => $row['date']
|
|
] );
|
|
|
|
$mdb -> delete( 'pro_rr_phrases_positions', [ 'id' => $row['id'] ] );
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Archiwizuję stare pozycje fraz | ID: <b>' . $row['id'] . '</b>, data: <b>' . $row['date'] . '</b>'
|
|
];
|
|
}
|
|
}
|
|
else
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
|
|
public static function check_proxy()
|
|
{
|
|
global $mdb, $config;
|
|
|
|
$results = $mdb -> query( 'SELECT '
|
|
. 'id, proxy, errors '
|
|
. 'FROM '
|
|
. 'pro_proxy_servers '
|
|
. 'WHERE '
|
|
. '( DATE_ADD( last_checked, INTERVAL 1 DAY ) < NOW() OR last_checked IS NULL ) '
|
|
. 'ORDER BY '
|
|
. 'last_checked ASC '
|
|
. 'LIMIT 1' ) -> fetchAll();
|
|
if ( is_array( $results ) and !empty( $results ) ) foreach ( $results as $row )
|
|
{
|
|
$result = \GoogleSite::checkProxyServerVersion( $row['proxy'] );
|
|
|
|
if ( $result['code'] == 404 or $result['result'] == '' and $result['code'] == 0 )
|
|
{
|
|
$mdb -> update( 'pro_proxy_servers', [ 'errors' => $row['errors'] + 1, 'last_checked' => \S::getDate() ], [ 'id' => $row['id'] ] );
|
|
$mdb -> delete( 'pro_proxy_servers', [ 'errors[>=]' => 7 ] );
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Sprawdzam poprawność proxy serwerowego: ' . $row['proxy'] . ' - ' . floatval( $result )
|
|
];
|
|
}
|
|
|
|
$ip = $result['info']['primary_ip'];
|
|
|
|
if ( !$result || $result != $config['proxy']['s-version'] )
|
|
$mdb -> update( 'pro_proxy_servers', [ 'last_checked' => \S::getDate(), 'errors' => 0, 'enabled' => 0, 'ip' => $ip ], [ 'id' => $row['id'] ] );
|
|
else
|
|
$mdb -> update( 'pro_proxy_servers', [ 'last_checked' => \S::getDate(), 'errors' => 0, 'enabled' => 1, 'ip' => $ip ], [ 'id' => $row['id'] ] );
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Sprawdzam poprawność proxy serwerowego: ' . $row['proxy'] . ' - ' . floatval( $result )
|
|
];
|
|
}
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
|
|
static public function get_phrases_positions_dfs3()
|
|
{
|
|
global $mdb;
|
|
|
|
$row = $mdb -> get( 'pro_rr_phrases', '*', [ 'AND' => [ 'ds_ready' => 1, 'ds_id[!]' => null ] ] );
|
|
if ( $row )
|
|
{
|
|
$client = new RestClient( 'https://api.dataforseo.com/', null, 'pyziak84@gmail.com', '0p4rYWDNoK63eUUw' );
|
|
$result = $client->get('/v3/serp/google/organic/task_get/advanced/' . $row['ds_id'] );
|
|
if ( $result['status_code'] == '20000' )
|
|
{
|
|
$sites = isset( $result['tasks'][0]['result'][0]['items'] ) ? $result['tasks'][0]['result'][0]['items'] : [];
|
|
$phrase_position = 0;
|
|
$site_url = '';
|
|
|
|
foreach ( $sites as $site )
|
|
{
|
|
if ( $site['type'] == 'organic' and \S::get_domain( $site['url'] ) == \S::get_domain( 'http://' . \factory\Ranker::get_domain_by_id( $row['site_id'] ) ) )
|
|
{
|
|
$phrase_position = $site['rank_group'];
|
|
$site_url = $site['url'];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( $mdb -> count( 'pro_rr_phrases_positions', [ 'AND' => [ 'phrase_id' => $row['id'], 'date' => date( 'Y-m-d' ) ] ] ) )
|
|
{
|
|
$mdb -> update( 'pro_rr_phrases_positions', [
|
|
'position' => (int)$phrase_position,
|
|
'url' => $site_url,
|
|
], [
|
|
'AND' => [
|
|
'phrase_id' => $row['id'],
|
|
'date' => date( 'Y-m-d' )
|
|
]
|
|
] );
|
|
}
|
|
else
|
|
{
|
|
$mdb -> insert( 'pro_rr_phrases_positions', [
|
|
'phrase_id' => $row['id'],
|
|
'position' => (int)$phrase_position,
|
|
'url' => $site_url,
|
|
'date' => date( 'Y-m-d' )
|
|
] );
|
|
|
|
$last_id = $mdb -> get( 'phrase_positions_statistic', 'id', [ 'phrase_id' => $row['id'], 'ORDER' => [ 'date' => 'DESC' ] ] );
|
|
|
|
if ( $last_id )
|
|
$mdb -> query( 'DELETE FROM phrase_positions_statistic WHERE phrase_id = ' . $row['id'] . ' AND id NOT IN ( ' . $last_id . ' )' );
|
|
|
|
$mdb -> insert( 'phrase_positions_statistic', [
|
|
'phrase_id' => $row['id'],
|
|
'position' => (int)$phrase_position,
|
|
'date' => date( 'Y-m-d' )
|
|
] );
|
|
}
|
|
|
|
$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 [
|
|
'status' => 'ok',
|
|
'msg' => 'Pobieramy wyniki dla frazy: <b>' . $row['phrase'] . '</b> - <b>' . (int)$phrase_position . '</b> - (API 3.0)'
|
|
];
|
|
}
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Pobieramy wyniki dla frazy: <b>' . $row['phrase'] . '</b> - BŁĄD - (API 3.0)'
|
|
];
|
|
}
|
|
}
|
|
|
|
static public function post_phrases_positions_dfs3()
|
|
{
|
|
global $mdb;
|
|
|
|
$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 = 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'] )
|
|
{
|
|
$post_array[0] = array(
|
|
"language_code" => "pl",
|
|
"location_code" => $row['localization'],
|
|
"keyword" => mb_convert_encoding( $row['phrase'], "UTF-8" ),
|
|
"priority" => 1,
|
|
'postback_data' => 'advanced',
|
|
'postback_url' => 'http://www.rank24.pl/dsf.php?d4s-id=$id',
|
|
'depth' => $depth
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$post_array[0] = array(
|
|
"language_code" => "pl",
|
|
"location_code" => $row['localization'],
|
|
"keyword" => mb_convert_encoding( $row['phrase'], "UTF-8" ),
|
|
"priority" => 1,
|
|
'postback_data' => 'advanced',
|
|
'postback_url' => 'http://www.rank24.pl/dsf.php?d4s-id=$id',
|
|
'depth' => $depth
|
|
);
|
|
}
|
|
|
|
$task_post_result = $client -> post( '/v3/serp/google/organic/task_post', $post_array );
|
|
|
|
if ( $task_post_result['status_code'] == '20000' )
|
|
{
|
|
$mdb -> update( 'pro_rr_phrases', [ 'ds_id' => $task_post_result['tasks'][0]['id'], 'ds_date' => date( 'Y-m-d' ) ], [ 'id' => $row['id'] ] );
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'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']
|
|
];
|
|
}
|
|
}
|
|
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
|
|
public static function check_phrases_positions_dfs()
|
|
{
|
|
global $mdb;
|
|
|
|
include 'autoload/RestClient.php';
|
|
|
|
$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';
|
|
$results = $mdb -> query( $sql ) -> fetchAll( \PDO::FETCH_ASSOC );
|
|
if ( is_array( $results ) and !empty( $results ) )
|
|
{
|
|
foreach ( $results as $row ) {
|
|
|
|
$client = new RestClient( 'https://api.dataforseo.com/', null, 'pyziak84@gmail.com', '0p4rYWDNoK63eUUw' );
|
|
|
|
if ( $row['localization'] and (int)$row['localization'] ) {
|
|
$post_array[0] = array(
|
|
"priority" => 1,
|
|
"site" => \S::get_domain( 'https://' . $row['url'] ),
|
|
"se_id" => 21,
|
|
"loc_id" => $row['localization'],
|
|
"key" => mb_convert_encoding( $row['phrase'], "UTF-8" ),
|
|
"key_id" => null,
|
|
'se_id' => 3433,
|
|
'postback_url' => 'http://www.rank24.pl/dsf.php'
|
|
);
|
|
}
|
|
else {
|
|
$post_array[0] = array(
|
|
"priority" => 1,
|
|
"site" => \S::get_domain( 'https://' . $row['url'] ),
|
|
"se_id" => 21,
|
|
"loc_name_canonical" => $row['localization'] ? $row['localization'] : 'Poland',
|
|
"key" => mb_convert_encoding( $row['phrase'], "UTF-8" ),
|
|
"key_id" => null,
|
|
'se_id' => 3433,
|
|
'postback_url' => 'http://www.rank24.pl/dsf.php'
|
|
);
|
|
}
|
|
|
|
$task_post_result = $client -> post( 'v2/rnk_tasks_post', array( 'data' => $post_array ) );
|
|
|
|
if ( $task_post_result['status'] == 'ok' ) {
|
|
|
|
$mdb -> update( 'pro_rr_phrases', [ 'ds_id' => $task_post_result['results'][0]['task_id'], 'ds_date' => date( 'Y-m-d' ) ], [ 'id' => $row['id'] ] );
|
|
|
|
if ( $row['localization'] != '' and !is_int( $row['localization'] ) ) {
|
|
$mdb -> update( 'pro_rr_phrases', [ 'localization' => $task_post_result['results'][0]['loc_id'] ], [ 'id' => $row['id'] ] );
|
|
}
|
|
|
|
return [
|
|
'status' => 'ok',
|
|
'msg' => 'Wysyłam do sprawdzenia frazę: <b>' . $row['phrase'] . '</b> - <b>' . $row['url'] . '</b>.'
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
return [ 'status' => 'empty' ];
|
|
}
|
|
}
|