- WordPress core y plugins - Tema Twenty Twenty-Four configurado - Plugin allow-unfiltered-html.php simplificado - .gitignore configurado para excluir wp-config.php y uploads 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
475 lines
12 KiB
PHP
Executable File
475 lines
12 KiB
PHP
Executable File
<?php
|
|
/**
|
|
* Database functions
|
|
*
|
|
* @link https://raiolanetworks.es
|
|
* @since 1.0.0
|
|
*
|
|
* @package Wp_Database_Tools
|
|
* @subpackage Wp_Database_Tools/includes
|
|
*/
|
|
|
|
/**
|
|
* Contains the functionalities related to find match.
|
|
*
|
|
* This class defines all features of the matching algorith.
|
|
*
|
|
* @since 1.0.0
|
|
* @package Wp_Database_Tools
|
|
* @subpackage Wp_Database_Tools/includes
|
|
* @author Raiola Networks <info@raiolanetworks.es>
|
|
*/
|
|
class Wp_Database_Tools_Matching {
|
|
|
|
/**
|
|
* The information of the plugins formatted
|
|
*
|
|
* @since 1.0.0
|
|
* @access protected
|
|
* @var array $plugins The plugins data.
|
|
*/
|
|
protected $plugins;
|
|
|
|
/**
|
|
* The information of the themes formatted
|
|
*
|
|
* @since 1.0.0
|
|
* @access protected
|
|
* @var array $themes The themes data.
|
|
*/
|
|
protected $themes;
|
|
|
|
/**
|
|
* Constructor
|
|
*
|
|
* Create the instance of a Matching.
|
|
*
|
|
* @access public
|
|
* @since 1.0.0
|
|
*
|
|
* @param Wp_Database_Tools_Plugins $plugins Plugin Obj.
|
|
* @param Wp_Database_Tools_Themes $themes Theme Obj.
|
|
*/
|
|
public function __construct( $plugins, $themes ) {
|
|
$this->plugins = $plugins->get_plugins();
|
|
$this->themes = $themes->get_themes();
|
|
}
|
|
|
|
/**
|
|
* Searches for possible matches of origins and returns matches
|
|
* sorted by the level of probability of a match.
|
|
*
|
|
* @access public
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $type Values plugin|theme.
|
|
* @param String $source_name Name of the source.
|
|
* @param String $source_value Value of the source.
|
|
*
|
|
* @return Array match found.
|
|
*/
|
|
public function find_match( $type, $source_name, $source_value ) {
|
|
|
|
$MATCHING_LVL = 100;
|
|
|
|
if ( 'plugin' === $type ) {
|
|
$search_origin = $this->plugins;
|
|
$search_text_domain = true;
|
|
}
|
|
|
|
if ( 'theme' === $type ) {
|
|
$search_origin = $this->themes;
|
|
$search_text_domain = false;
|
|
}
|
|
|
|
$concidences_slugs = array();
|
|
|
|
// We go through all possible sources (plugins or themes) looking for matches.
|
|
foreach ( $search_origin as $key => $origin ) {
|
|
|
|
// Porcent match.
|
|
$match_results = array();
|
|
|
|
// Text Domain.
|
|
if ( $search_text_domain === true ) {
|
|
|
|
$text_domain = $origin['text_domain'];
|
|
|
|
$match = $this->search_by_text_domain( $text_domain, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
}
|
|
|
|
// Slugs.
|
|
$slug = $origin['slug'];
|
|
$name = $origin['name'];
|
|
|
|
if ( $source_value !== null ) {
|
|
|
|
if ( str_contains( $source_name, 'edd_' ) ) {
|
|
$match = $this->search_by_value( $slug, $name, $source_value );
|
|
array_push( $match_results, $match );
|
|
}
|
|
}
|
|
|
|
$match = $this->search_by_text_slug( $slug, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
// Initials.
|
|
$initials = $origin['initials'];
|
|
|
|
if ( strlen( $initials ) >= 3 && strlen( $initials ) <= 5 ) {
|
|
|
|
$match = $this->search_by_starts_initials( $initials, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
if ( str_contains( $slug, 'premium' ) || str_contains( $slug, 'pro' ) ) {
|
|
|
|
if ( substr( $initials, -1 ) == 'p' ) {
|
|
|
|
$match = $this->search_by_starts_initials_without_last( $initials, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
}
|
|
}
|
|
|
|
$match = $this->search_by_starts_initials_similar( $initials, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
}
|
|
|
|
$match = $this->search_by_similar_slug( $slug, $source_name );
|
|
array_push( $match_results, $match );
|
|
|
|
// Search main file.
|
|
if ( isset( $origin['path'] ) ) {
|
|
|
|
$path = $origin['path'];
|
|
$match = $this->search_main_file( $path, $source_name, $initials );
|
|
array_push( $match_results, $match );
|
|
|
|
}
|
|
|
|
// Order array.
|
|
asort( $match_results );
|
|
|
|
$concidences_slugs[ $slug ] = end( $match_results );
|
|
|
|
unset( $origin );
|
|
}
|
|
|
|
// Order array.
|
|
asort( $concidences_slugs );
|
|
|
|
// Get value if the match if hightest.
|
|
if ( end( $concidences_slugs ) >= $MATCHING_LVL ) {
|
|
|
|
$data_return = array(
|
|
'slug' => array_key_last( $concidences_slugs ),
|
|
'match' => end( $concidences_slugs ),
|
|
);
|
|
|
|
return $data_return;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
/**
|
|
* Return longest char match between two strings
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $str1 First string to compare.
|
|
* @param String $str2 Second string to compare.
|
|
*
|
|
* @return int longest match.
|
|
*/
|
|
protected function get_longest_matching_substring( $str1, $str2 ) {
|
|
$len_1 = strlen( $str1 );
|
|
$longest = '';
|
|
for ( $i = 0; $i < $len_1; $i++ ) {
|
|
for ( $j = $len_1 - $i; $j > 0; $j-- ) {
|
|
$sub = substr( $str1, $i, $j );
|
|
if ( strpos( $str2, $sub ) !== false && strlen( $sub ) > strlen( $longest ) ) {
|
|
$longest = $sub;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return strlen( $longest );
|
|
}
|
|
|
|
/**
|
|
* Compare the slug of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* The comparison is done by looking for an exact match of the same string
|
|
* at its beginning.
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $slug Slug of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int longest match.
|
|
*/
|
|
protected function search_by_similar_slug( $slug, $source_name ) {
|
|
|
|
$slug_name = preg_split( '/-|_/', $slug );
|
|
|
|
$source_name = str_replace( array( '_', '-' ), '_', $source_name );
|
|
$match = 0;
|
|
|
|
foreach ( $slug_name as $key => $slug ) {
|
|
|
|
if ( $key == 0 ) {
|
|
$slug_search = $slug_name[0] . '_';
|
|
}
|
|
if ( $key == 1 ) {
|
|
$slug_search = $slug_name[0] . '_' . $slug_name[1] . '_';
|
|
}
|
|
if ( $key == 2 ) {
|
|
$slug_search = $slug_name[0] . '_' . $slug_name[1] . '_' . $slug_name[2] . '_';
|
|
}
|
|
|
|
$slug_length = strlen( $slug_search );
|
|
|
|
if ( str_starts_with( $source_name, $slug_search ) && $slug_length > 3 ) {
|
|
$match += $slug_length + 100;
|
|
}
|
|
}
|
|
|
|
return $match;
|
|
|
|
}
|
|
|
|
/**
|
|
* Compare the slug of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* The comparison is made on the basis of the highest coincidence between
|
|
* the achievement of their chars.
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $slug Slug of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int longest match.
|
|
*/
|
|
protected function search_by_text_slug( $slug, $source_name ) {
|
|
$slug = str_replace( array( '_', '-' ), '', $slug );
|
|
$source_name = str_replace( array( '_', '-' ), '', $source_name );
|
|
$slug = strtolower( $slug );
|
|
$source_name = strtolower( $source_name );
|
|
$slug_length = strlen( $slug );
|
|
$result = $this->get_longest_matching_substring( $slug, $source_name );
|
|
$match = ( $result * 100 ) / $slug_length;
|
|
$match += $slug_length;
|
|
return $match;
|
|
}
|
|
|
|
/**
|
|
* Compare text_domain slug of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* The comparison is made on the basis of the highest coincidence between
|
|
* the achievement of their chars.
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $text_domain Slug of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_by_text_domain( $text_domain, $source_name ) {
|
|
$text_domain = str_replace( array( '_', '-' ), '', $text_domain );
|
|
$source_name = str_replace( array( '_', '-' ), '', $source_name );
|
|
$text_domain = strtolower( $text_domain );
|
|
$source_name = strtolower( $source_name );
|
|
$text_domain_length = strlen( $text_domain );
|
|
$result = $this->get_longest_matching_substring( $text_domain, $source_name );
|
|
$match = ( $result * 100 ) / $text_domain_length;
|
|
$match += $text_domain_length;
|
|
return $match;
|
|
}
|
|
|
|
/**
|
|
* Compare initials of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $initials Initials of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_by_starts_initials( $initials, $source_name ) {
|
|
|
|
$source_name = preg_split( '/-|_/', $source_name );
|
|
|
|
if ( count( $source_name ) > 1 ) {
|
|
$start_name = $source_name[0];
|
|
$match = ( $start_name === $initials ) ? 100 : 0;
|
|
return $match;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/**
|
|
* Compare initials of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* We search by initials omitting the last character.
|
|
* This is checked to avoid comparisons with words
|
|
* like "pro" or "lite" at the end.
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $initials Initials of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_by_starts_initials_without_last( $initials, $source_name ) {
|
|
|
|
$source_name = preg_split( '/-|_/', $source_name );
|
|
|
|
if ( count( $source_name ) > 1 ) {
|
|
$start_name = $source_name[0];
|
|
$match = ( $start_name == substr_replace( $initials, '', -1 ) ) ? 100 : 0;
|
|
return $match;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
/**
|
|
* Compare initials of the plugin or theme with the name of the source
|
|
* (options, cronjobs...) to find a match.
|
|
*
|
|
* We compare the similarity of the initials
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $initials Initials of origin.
|
|
* @param String $source_name Name of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_by_starts_initials_similar( $initials, $source_name ) {
|
|
|
|
$initials = strtolower( $initials );
|
|
$source_name = strtolower( $source_name );
|
|
$source_name = preg_split( '/-|_/', $source_name );
|
|
|
|
if ( count( $source_name ) > 1 ) {
|
|
$start_name = $source_name[0];
|
|
similar_text( $initials, $start_name, $match );
|
|
return $match;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/**
|
|
* We look for matches in the value of the origins (options,tables,cronjobs)
|
|
* by comparing with the slug and name of the source (themes,plugins).
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $slug Initials of origin.
|
|
* @param String $name Name of the source.
|
|
* @param String $source_value Name of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_by_value( $slug, $name, $source_value ) {
|
|
|
|
$content = strtolower( $source_value );
|
|
|
|
if ( str_contains( $content, strtolower( $slug ) ) ) {
|
|
return 100;
|
|
}
|
|
|
|
if ( str_contains( $content, strtolower( $name ) ) ) {
|
|
return 100;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/**
|
|
* We look for matches in the origins file (themes,plugins)
|
|
* comparing with the value of the sources (cronjobs,options,tables).
|
|
*
|
|
* @access protected
|
|
* @since 1.0.0
|
|
*
|
|
* @param String $path The file path.
|
|
* @param String $source_name Name of the source.
|
|
* @param String $initials Initials of the source.
|
|
*
|
|
* @return int match.
|
|
*/
|
|
protected function search_main_file( $path, $source_name, $initials ) {
|
|
|
|
$prefix_source = preg_split( '/-|_/', $source_name );
|
|
|
|
if ( count( $prefix_source ) > 1 ) {
|
|
|
|
if ( $prefix_source[0] != 'edd' ) {
|
|
|
|
if ( strlen( $prefix_source[0] ) >= 3 ) {
|
|
|
|
$content = strtolower( file_get_contents( WP_PLUGIN_DIR . '/' . $path ) );
|
|
$regex = '/("|\')' . $prefix_source[0] . '(_|-)/i';
|
|
|
|
// Search on main file.
|
|
preg_match( $regex, $content, $concidences );
|
|
|
|
if ( count( $concidences ) > 0 ) {
|
|
|
|
similar_text( $concidences[0], $prefix_source[0], $percent );
|
|
|
|
if ( $percent >= 80 ) {
|
|
return intval( $percent );
|
|
}
|
|
|
|
similar_text( $concidences[0], $initials, $percent );
|
|
|
|
if ( $percent >= 80 ) {
|
|
return intval( $percent );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|