Restore to commit 74e578279624c6045ca440a3459ebfa1f8d54191
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Check for duplicate class declarations in WordPress plugin
|
||||
* Detects duplicate classes, interfaces, traits, functions, and constants
|
||||
*/
|
||||
|
||||
$plugin_dir = $argv[1] ?? __DIR__;
|
||||
|
||||
echo "=== Checking for Duplicates ===\n\n";
|
||||
|
||||
function scan_directory($dir, $extensions = ['php']) {
|
||||
$files = [];
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if (in_array(strtolower($file->getExtension()), $extensions)) {
|
||||
$files[] = $file->getPathname();
|
||||
}
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
function extract_declarations($content) {
|
||||
$declarations = [];
|
||||
|
||||
// Extract classes
|
||||
if (preg_match_all('/^\s*(?:abstract\s+)?class\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $class) {
|
||||
$declarations['classes'][$class][] = 'class';
|
||||
}
|
||||
}
|
||||
|
||||
// Extract interfaces
|
||||
if (preg_match_all('/^\s*interface\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $interface) {
|
||||
$declarations['interfaces'][$interface][] = 'interface';
|
||||
}
|
||||
}
|
||||
|
||||
// Extract traits
|
||||
if (preg_match_all('/^\s*trait\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $trait) {
|
||||
$declarations['traits'][$trait][] = 'trait';
|
||||
}
|
||||
}
|
||||
|
||||
// Extract functions (non-namespaced)
|
||||
if (preg_match_all('/^\s*function\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $function) {
|
||||
if (!isset($declarations['functions'][$function])) {
|
||||
$declarations['functions'][$function] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $declarations;
|
||||
}
|
||||
|
||||
function check_duplicate_classes($files) {
|
||||
$all_classes = [];
|
||||
$duplicates = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$content = file_get_contents($file);
|
||||
|
||||
// Check for classes
|
||||
if (preg_match_all('/^\s*(?:abstract\s+)?class\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $class) {
|
||||
if (!isset($all_classes[$class])) {
|
||||
$all_classes[$class] = [];
|
||||
}
|
||||
$all_classes[$class][] = $file;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for interfaces
|
||||
if (preg_match_all('/^\s*interface\s+(\w+)/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $interface) {
|
||||
$key = strtolower($interface);
|
||||
if (!isset($all_classes[$key])) {
|
||||
$all_classes[$key] = [];
|
||||
}
|
||||
$all_classes[$key][] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($all_classes as $name => $files_list) {
|
||||
if (count($files_list) > 1) {
|
||||
$duplicates['classes'][$name] = $files_list;
|
||||
}
|
||||
}
|
||||
|
||||
return $duplicates;
|
||||
}
|
||||
|
||||
function check_duplicate_functions($files) {
|
||||
$all_functions = [];
|
||||
$duplicates = [];
|
||||
|
||||
foreach ($files as $file) {
|
||||
$content = file_get_contents($file);
|
||||
|
||||
// Skip content inside classes, interfaces, and traits
|
||||
$content = preg_replace('/class\s+\w+\s*\{[^}]*\}/s', '', $content);
|
||||
$content = preg_replace('/interface\s+\w+\s*\{[^}]*\}/s', '', $content);
|
||||
$content = preg_replace('/trait\s+\w+\s*\{[^}]*\}/s', '', $content);
|
||||
|
||||
if (preg_match_all('/^\s*function\s+(\w+)\s*\(/m', $content, $matches)) {
|
||||
foreach ($matches[1] as $function) {
|
||||
if (!isset($all_functions[$function])) {
|
||||
$all_functions[$function] = [];
|
||||
}
|
||||
$all_functions[$function][] = $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($all_functions as $name => $files_list) {
|
||||
if (count($files_list) > 1) {
|
||||
$duplicates['functions'][$name] = $files_list;
|
||||
}
|
||||
}
|
||||
|
||||
return $duplicates;
|
||||
}
|
||||
|
||||
echo "Scanning directory: $plugin_dir\n";
|
||||
$files = scan_directory($plugin_dir);
|
||||
echo "Found " . count($files) . " PHP files\n\n";
|
||||
|
||||
$class_duplicates = check_duplicate_classes($files);
|
||||
$function_duplicates = check_duplicate_functions($files);
|
||||
|
||||
$has_issues = false;
|
||||
|
||||
if (!empty($class_duplicates['classes'])) {
|
||||
$has_issues = true;
|
||||
echo "❌ Duplicate class/interface declarations found:\n";
|
||||
foreach ($class_duplicates['classes'] as $name => $files_list) {
|
||||
echo " - $name found in:\n";
|
||||
foreach ($files_list as $file) {
|
||||
echo " $file\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if (!empty($function_duplicates['functions'])) {
|
||||
$has_issues = true;
|
||||
echo "⚠️ Potential duplicate function declarations:\n";
|
||||
foreach ($function_duplicates['functions'] as $name => $files_list) {
|
||||
echo " - $name() found in:\n";
|
||||
foreach ($files_list as $file) {
|
||||
echo " $file\n";
|
||||
}
|
||||
}
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
if (!$has_issues) {
|
||||
echo "✅ No duplicate declarations found\n";
|
||||
} else {
|
||||
echo "⚠️ Please review the duplicates above and fix them.\n";
|
||||
echo " Solutions:\n";
|
||||
echo " - Use class_exists() guards around class definitions\n";
|
||||
echo " - Consolidate duplicate declarations into one file\n";
|
||||
echo " - Namespace conflicting classes differently\n";
|
||||
}
|
||||
|
||||
echo "\n=== Check Complete ===\n";
|
||||
exit($has_issues ? 1 : 0);
|
||||
@@ -0,0 +1,195 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WordPress Plugin Validation Script
|
||||
# Validates plugin structure, syntax, and WordPress coding standards
|
||||
|
||||
PLUGIN_DIR="$(pwd)"
|
||||
PLUGIN_SLUG="pc-community-suggestions-7d3f"
|
||||
MAIN_FILE="$PLUGIN_SLUG.php"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${BLUE}=== WordPress Plugin Validation ===${NC}"
|
||||
echo -e "Plugin: $PLUGIN_SLUG"
|
||||
echo -e "Directory: $PLUGIN_DIR"
|
||||
echo
|
||||
|
||||
# Check if main plugin file exists
|
||||
if [[ ! -f "$MAIN_FILE" ]]; then
|
||||
echo -e "${RED}❌ ERROR: Main plugin file $MAIN_FILE not found${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Main plugin file found${NC}"
|
||||
|
||||
# Check plugin header
|
||||
echo -e "${BLUE}Checking plugin header...${NC}"
|
||||
if ! grep -q "Plugin Name:" "$MAIN_FILE"; then
|
||||
echo -e "${RED}❌ ERROR: Plugin header missing 'Plugin Name:'${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q "Plugin URI:" "$MAIN_FILE"; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: Plugin header missing 'Plugin URI:'${NC}"
|
||||
fi
|
||||
|
||||
if ! grep -q "Text Domain:" "$MAIN_FILE"; then
|
||||
echo -e "${RED}❌ ERROR: Plugin header missing 'Text Domain:'${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! grep -q "Update URI:" "$MAIN_FILE"; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: Plugin header missing 'Update URI:'${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}✅ Plugin header check passed${NC}"
|
||||
|
||||
# Check required directories
|
||||
echo -e "${BLUE}Checking directory structure...${NC}"
|
||||
REQUIRED_DIRS=("includes" "admin" "admin/css" "admin/js" "public" "public/css" "public/js" "assets")
|
||||
|
||||
for dir in "${REQUIRED_DIRS[@]}"; do
|
||||
if [[ ! -d "$dir" ]]; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: Directory $dir not found${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✅ Directory $dir found${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check required files
|
||||
echo -e "${BLUE}Checking required files...${NC}"
|
||||
REQUIRED_FILES=(
|
||||
"includes/class-database.php"
|
||||
"includes/class-shortcodes.php"
|
||||
"includes/class-rest-api.php"
|
||||
"admin/class-admin.php"
|
||||
"admin/css/admin-style.css"
|
||||
"public/css/public-style.css"
|
||||
"public/js/public-script.js"
|
||||
"admin/js/admin-script.js"
|
||||
"uninstall.php"
|
||||
)
|
||||
|
||||
for file in "${REQUIRED_FILES[@]}"; do
|
||||
if [[ ! -f "$file" ]]; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: File $file not found${NC}"
|
||||
else
|
||||
echo -e "${GREEN}✅ File $file found${NC}"
|
||||
fi
|
||||
done
|
||||
|
||||
# PHP syntax check
|
||||
echo -e "${BLUE}Running PHP syntax checks...${NC}"
|
||||
PHP_FILES=$(find . -name "*.php" -type f)
|
||||
SYNTAX_ERRORS=0
|
||||
|
||||
for php_file in $PHP_FILES; do
|
||||
if php -l "$php_file" > /dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Syntax OK: $php_file${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Syntax ERROR: $php_file${NC}"
|
||||
php -l "$php_file"
|
||||
SYNTAX_ERRORS=$((SYNTAX_ERRORS + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SYNTAX_ERRORS -gt 0 ]]; then
|
||||
echo -e "${RED}❌ Found $SYNTAX_ERRORS PHP syntax errors${NC}"
|
||||
exit 1
|
||||
else
|
||||
echo -e "${GREEN}✅ All PHP files passed syntax check${NC}"
|
||||
fi
|
||||
|
||||
# Check for WordPress functions
|
||||
echo -e "${BLUE}Checking WordPress function usage...${NC}"
|
||||
if ! grep -q "add_action\|add_filter" "$MAIN_FILE"; then
|
||||
echo -e "${YELLOW}⚠️ WARNING: No WordPress hooks found in main file${NC}"
|
||||
fi
|
||||
|
||||
# Check for proper enqueueing
|
||||
echo -e "${BLUE}Checking script enqueueing...${NC}"
|
||||
if grep -q "wp_enqueue_style\|wp_enqueue_script" "$MAIN_FILE"; then
|
||||
echo -e "${GREEN}✅ Script enqueueing functions found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No script enqueueing functions found${NC}"
|
||||
fi
|
||||
|
||||
# Check for security measures
|
||||
echo -e "${BLUE}Checking security measures...${NC}"
|
||||
if grep -q "check_admin_referer\|wp_verify_nonce" "$MAIN_FILE" || grep -q "check_admin_referer\|wp_verify_nonce" includes/*.php; then
|
||||
echo -e "${GREEN}✅ Security nonce checks found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No security nonce checks found${NC}"
|
||||
fi
|
||||
|
||||
if grep -q "current_user_can\|is_user_logged_in" "$MAIN_FILE" || grep -q "current_user_can\|is_user_logged_in" includes/*.php; then
|
||||
echo -e "${GREEN}✅ User capability checks found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No user capability checks found${NC}"
|
||||
fi
|
||||
|
||||
# Check for database operations
|
||||
echo -e "${BLUE}Checking database operations...${NC}"
|
||||
if grep -q "\$wpdb->" includes/class-database.php; then
|
||||
echo -e "${GREEN}✅ Database operations found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No database operations found${NC}"
|
||||
fi
|
||||
|
||||
# Check for activation/deactivation hooks
|
||||
echo -e "${BLUE}Checking activation hooks...${NC}"
|
||||
if grep -q "register_activation_hook\|register_deactivation_hook" "$MAIN_FILE"; then
|
||||
echo -e "${GREEN}✅ Activation/deactivation hooks found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No activation/deactivation hooks found${NC}"
|
||||
fi
|
||||
|
||||
# Check for shortcodes
|
||||
echo -e "${BLUE}Checking shortcodes...${NC}"
|
||||
if grep -q "add_shortcode" includes/class-shortcodes.php; then
|
||||
echo -e "${GREEN}✅ Shortcode registration found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No shortcode registration found${NC}"
|
||||
fi
|
||||
|
||||
# Check for REST API
|
||||
echo -e "${BLUE}Checking REST API...${NC}"
|
||||
if grep -q "register_rest_route" includes/class-rest-api.php; then
|
||||
echo -e "${GREEN}✅ REST API routes found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No REST API routes found${NC}"
|
||||
fi
|
||||
|
||||
# Check for admin menu
|
||||
echo -e "${BLUE}Checking admin menu...${NC}"
|
||||
if grep -q "add_menu_page\|add_submenu_page" admin/class-admin.php; then
|
||||
echo -e "${GREEN}✅ Admin menu registration found${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ WARNING: No admin menu registration found${NC}"
|
||||
fi
|
||||
|
||||
# Final summary
|
||||
echo
|
||||
echo -e "${BLUE}=== Validation Summary ===${NC}"
|
||||
echo -e "${GREEN}✅ Plugin structure looks good${NC}"
|
||||
echo -e "${GREEN}✅ All PHP files passed syntax check${NC}"
|
||||
echo -e "${GREEN}✅ WordPress integration features found${NC}"
|
||||
echo -e "${GREEN}✅ Security measures implemented${NC}"
|
||||
echo
|
||||
echo -e "${GREEN}🎉 Plugin validation completed successfully!${NC}"
|
||||
echo -e "${BLUE}The plugin is ready for WordPress installation.${NC}"
|
||||
|
||||
# Display plugin information
|
||||
echo
|
||||
echo -e "${BLUE}=== Plugin Information ===${NC}"
|
||||
grep "Plugin Name:" "$MAIN_FILE" | head -1
|
||||
grep "Version:" "$MAIN_FILE" | head -1
|
||||
grep "Author:" "$MAIN_FILE" | head -1
|
||||
grep "Text Domain:" "$MAIN_FILE" | head -1
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user