ACPT Pro 2.1.6: what Rateo prints

The Rateo engine, run on ACPT Pro, a custom post type and fields plugin. Every number below comes from the engine's output, which is linked in full at the end.

ACPT Pro is made by the team behind Rateo. We ran it on our own code first.

License
GPL-2.0-or-later
Source
ACPT Pro release zip, available to customers
Engine
2026.10.12
Rules
2026.10.7-provisional
Ran on
2026-10-16
Zip SHA-256
613dd8ffa9c8f04ca05438a95105c4d021febd707559e14c2d0c73073ae4c1b3
Command
build/rateo advanced-custom-post-type --cache=none
from the folder the zip was extracted into

At a glance

Files analysed
1,062
Findings
3,480
Errors
452
Warnings
3,028

platform PHP: WordPress (plugin header in advanced-custom-post-type.php)

not analysed: 550 files (binary 271, JavaScript 215, CSS 35, Gettext Catalog 16, JSON 4, SVG 3, Markdown 2, INI 1, Ignore List 1, YAML 1, dist 1)

Folders and files not analysed, by reason: Dependency 2.

What it checks

Checked today

  • Size: long files, classes and functions
  • Complexity: functions and file level code with too many paths
  • Naming: mixed styles in a file, generic, one letter and very long names
  • Duplication: blocks repeated inside a file, even with renamed variables
  • Security: eval, shell commands, unserialize and includes built from data, SQL with values pasted in, request input never sanitized, output never escaped

Not checked yet

  • WordPress rules: nonces and capability checks

The security checks read one call or statement at a time and never follow a value through variables, so they show where to look, not proof of a hole. A long or branchy function is common in a large, mature plugin; each finding is a place worth a closer look, not a judgement of the code as a whole.

Findings by check

CheckLimits (warning / error)WarningsErrorsTotal
Size
length.function
A function or method body with too many lines
body lines: above 50 / above 100421201622
length.class
A class with too many lines
lines: above 500 / above 1000 (other)453277
length.file
A file with too many lines
lines: above 600 / above 1200 (other)382462
Complexity
complexity.function
A function or method with too many paths through it
cyclomatic complexity: above 10 / above 20363195558
complexity.file_code
Code outside any function with too many paths through it
cyclomatic complexity: above 10 / above 20101
Duplication
duplication.repeated_block
A block repeated later in the same file, even with its names changed
tokens: 50 or more / never an error1,16501,165
Naming
naming.inconsistent_style
A name in a different style from most names of its kind in the file
style: differs from the file's main style (groups of 3 or more names) / never an error3350335
naming.generic
A local variable or parameter with a name that says nothing, like $data or $tmp
name: on the list of 16 generic names / never an error1910191
naming.too_short
A one letter name other than i, j, k, n, x, y, z or e
characters: under 2 / never an error1360136
naming.too_long
A very long name
characters: above 30 / never an error1540154

A value equal to a limit is no finding.

Where they concentrate

The 10 files with the most findings

FileFindings
advanced-custom-post-type/src/Integrations/Bricks/providers/provider-acpt.php108
advanced-custom-post-type/src/Core/API/V1/Controllers/SchemaController.php96
advanced-custom-post-type/src/Includes/ACPT_Schema.php90
advanced-custom-post-type/src/Core/Repository/MetaRepository.php77
advanced-custom-post-type/functions/_inc/values/meta_get.php74
advanced-custom-post-type/src/Core/CQRS/Query/FetchMetaFieldValueQuery.php73
advanced-custom-post-type/src/Core/CQRS/Query/FetchFormFieldsQuery.php71
advanced-custom-post-type/src/Core/Generators/Table/TableRecordPageGenerator.php48
advanced-custom-post-type/src/Integrations/WPAllImport/Helper/RapidAddon.php46
advanced-custom-post-type/src/Core/API/AJAX/Controllers/MetaController.php44

Findings per top level folder

FolderFindings
src/3,280
functions/148
migrations/41
admin/6
init/5

Grades

BOverall: 82 out of 100
3 of 5 metrics graded

round((3 × 87Complexity+2 × 66Duplication+1 × 96Naming) ÷ 6) = 82

Weights: Complexity 3, Duplication 2, Naming 1. Size and Security are not graded, so they are left out and the other weights are rescaled.

A summary of the grades below, which you can recompute. Not a pass mark, and not a hiring decision.

The table shows how many files got each letter. A file with nothing to judge for a metric gets no grade for it. The whole plugin column pools every file's grade, so a file with more code to judge counts for more. The overall above weights those whole plugin grades. In the full engine output these are CodeLength, CyclomaticComplexity, Duplication, NamingConvention and Security.

MetricABCDFNot gradedWhole plugin
SizeFindings only, no grade
Complexity767687814825387 B
Duplication86025600115266 D
Naming962702214396 A
SecurityFindings only, no grade

Security

Findings only, never a grade: a wrong security grade would hurt more than none. A finding the author already silenced with a phpcs comment counts as suppressed, apart from Errors and Warnings, so you can tell reviewed code from unreviewed code.

CheckErrorsWarningsSuppressed
security.eval
A call to eval, which runs a string as PHP code
000
security.shell
A shell command built from data
000
security.unserialize
unserialize without allowed_classes => false
000
security.include_variable
An include or require whose path is built from a variable
050
security.extract_input
extract of request input, which turns its fields into variables
000
security.sql_interpolated
SQL with a value pasted in instead of passed through prepare
0108
security.unescaped_output
An echo, print or <?= of a value that is not escaped
01170
security.unsanitized_input
A request input read with no sanitizer around it
0470

Where to look first

Up to 10 places, Errors first, then Warnings, then by path and line. An Error means request input reaches the call or the output directly.

#1 advanced-custom-post-type/admin/templates/app.php:31

  • Warning security.unescaped_output

    echo of `strtoupper(ACPT_SKIN)` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

31 <!-- ACPT <?php echo strtoupper(ACPT_SKIN); ?> SKIN -->
32 <style>
33 #wpfooter, #wpcontent {
34 background: <?php echo $footerBg; ?>;
35 color: <?php echo $footerColor; ?>;
36 }
37
38 #wpfooter a {
39 color: <?php echo $footerLinkColor; ?>;
40 }

#2 advanced-custom-post-type/admin/templates/app.php:34

  • Warning security.unescaped_output

    echo of `$footerBg` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

34 background: <?php echo $footerBg; ?>;
35 color: <?php echo $footerColor; ?>;
36 }
37
38 #wpfooter a {
39 color: <?php echo $footerLinkColor; ?>;
40 }
41
42 #wpfooter a:hover,
43 #wpfooter a:focus {

#3 advanced-custom-post-type/admin/templates/app.php:35

  • Warning security.unescaped_output

    echo of `$footerColor` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

35 color: <?php echo $footerColor; ?>;
36 }
37
38 #wpfooter a {
39 color: <?php echo $footerLinkColor; ?>;
40 }
41
42 #wpfooter a:hover,
43 #wpfooter a:focus {
44 color: <?php echo $footerLinkHoverColor; ?>;

#4 advanced-custom-post-type/admin/templates/app.php:39

  • Warning security.unescaped_output

    echo of `$footerLinkColor` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

39 color: <?php echo $footerLinkColor; ?>;
40 }
41
42 #wpfooter a:hover,
43 #wpfooter a:focus {
44 color: <?php echo $footerLinkHoverColor; ?>;
45 }
46
47 ul#adminmenu a.wp-has-current-submenu:after {
48 border-right-color: <?php echo $footerBg; ?>;

#5 advanced-custom-post-type/admin/templates/app.php:44

  • Warning security.unescaped_output

    echo of `$footerLinkHoverColor` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

44 color: <?php echo $footerLinkHoverColor; ?>;
45 }
46
47 ul#adminmenu a.wp-has-current-submenu:after {
48 border-right-color: <?php echo $footerBg; ?>;
49 }
50 </style>
51<?php endif; ?>

#6 advanced-custom-post-type/admin/templates/app.php:48

  • Warning security.unescaped_output

    echo of `$footerBg` is not escaped at output; escape where you print (esc_html, esc_attr, htmlspecialchars)

48 border-right-color: <?php echo $footerBg; ?>;
49 }
50 </style>
51<?php endif; ?>

#7 advanced-custom-post-type/migrations/202604010001_migrate_location_data_to_junction.php:76

  • Warning security.sql_interpolated

    query `$wpdb->get_results` builds its SQL from `$prefixedName`; pass values through prepare with placeholders to prevent SQL injection

76 $columns = $wpdb->get_results("SHOW COLUMNS FROM `{$prefixedName}` LIKE 'location_rule'");
77
78 if (empty($columns)) {
79 continue;
80 }
81
82 // Copy existing data to junction table
83 ACPT_DB::executeQueryOrThrowException(
84 "INSERT IGNORE INTO `{$junctionTable}` (table_name, record_id, location_rule, location_value)
85 SELECT %s, id, location_rule, location_value

#8 advanced-custom-post-type/migrations/202604010001_migrate_location_data_to_junction.php:92

  • Warning security.sql_interpolated

    query `$wpdb->query` builds its SQL from `$prefixedName`; pass values through prepare with placeholders to prevent SQL injection

92 $wpdb->query("ALTER TABLE `{$prefixedName}` DROP INDEX `idx_location`");
93 $wpdb->query("ALTER TABLE `{$prefixedName}` DROP COLUMN `location_rule`, DROP COLUMN `location_value`");
94 }
95 }
96}

#9 advanced-custom-post-type/migrations/202604010001_migrate_location_data_to_junction.php:93

  • Warning security.sql_interpolated

    query `$wpdb->query` builds its SQL from `$prefixedName`; pass values through prepare with placeholders to prevent SQL injection

93 $wpdb->query("ALTER TABLE `{$prefixedName}` DROP COLUMN `location_rule`, DROP COLUMN `location_value`");
94 }
95 }
96}

#10 advanced-custom-post-type/src/Admin/ACPT_Admin.php:379

  • Warning security.include_variable

    require_once of `$template` builds the file path from data; a crafted path can load another file

379 require_once plugin_dir_path(dirname(__FILE__)) . '../admin/templates/'.$template.'.php';
380 },
381 $position
382 );
383 } else {
384 add_menu_page(
385 $pageTitle,
386 $menuTitle,
387 $capability,
388 $menuSlug,

The 10 worst places

Security findings are listed in their own section above. A place is a file and a line, so a function that is both too long and too complex shows once, with both findings. Places rank by their worst finding: errors first, then by how far the measured value goes beyond its limit. Each message is the engine's own, word for word.

2 places are left out of this list because the engine flags them by mistake: advanced-custom-post-type/src/Includes/ACPT_Schema.php:19, the plugin's database tables written as one array of data, not logic; advanced-custom-post-type/src/Core/API/V1/Controllers/SchemaController.php:189, the plugin's API description written as one array of data, not logic. Their findings still count in the grades, the tables above and the full output.

#1 advanced-custom-post-type/src/Integrations/Bricks/providers/provider-acpt.php:699

  • Error complexity.function

    Provider_ACPT::get_tag_value has a cyclomatic complexity of 298, untestable risk (above 10): each of its 298 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    Provider_ACPT::get_tag_value has 1104 lines in its body, above 100

699 public function get_tag_value($tag, $post, $args, $context)
700 {
701 try {
702 // A Toggle without a value must not reuse the previous loop item's (#1419)
703 unset(self::$condition_toggle_values[$tag]);
704
705 if (!isset($this->tags[$tag])) {
706 return null;
707 }
708

#2 advanced-custom-post-type/src/Integrations/Gutenberg/Generators/ACPTBlocks/Blocks/RepeaterLoopBlockRenderer.php:282

  • Error complexity.function

    RepeaterLoopBlockRenderer::realValue has a cyclomatic complexity of 264, untestable risk (above 10): each of its 264 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    RepeaterLoopBlockRenderer::realValue has 751 lines in its body, above 100

282 private function realValue(string $fieldType, $rawValue, array $parsed = [], $before = null, $after = null)
283 {
284 $raw = $parsed['raw'] ?? false;
285 $subKey = $parsed['subKey'] ?? null;
286 $args = $parsed['args'] ?? [];
287
288 // Legacy: if $parsed is a plain array of args (old callers), keep working
289 if (isset($parsed[0])) {
290 $args = $parsed;
291 $raw = false;

#3 advanced-custom-post-type/src/Integrations/Gutenberg/Generators/ACPTBlocks/Blocks/BasicBlockRenderer.php:65

  • Error complexity.function

    BasicBlockRenderer::getRawData has a cyclomatic complexity of 260, untestable risk (above 10): each of its 260 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    BasicBlockRenderer::getRawData has 877 lines in its body, above 100

65 private function getRawData(array $field, array $attributes = [])
66 {
67 $findValue = null;
68
69 // try to calculate $find and $findValue
70 if (isset($field['belongsTo']) && $field['belongsTo'] === MetaTypes::OPTION_PAGE) {
71 $findValue = $field['find'];
72 $find = 'option_page';
73 } elseif (isset($field['belongsTo']) && $field['belongsTo'] === MetaTypes::TAXONOMY) {
74 $find = 'term_id';

#4 advanced-custom-post-type/src/Core/CQRS/Command/SaveMetaFieldValueCommand.php:73

  • Error complexity.function

    SaveMetaFieldValueCommand::execute has a cyclomatic complexity of 210, untestable risk (above 10): each of its 210 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    SaveMetaFieldValueCommand::execute has 977 lines in its body, above 100

73 public function execute(): bool
74 {
75 $metaFieldModelType = $this->fieldModel->getType();
76 $savedFieldValue = $this->get($this->fieldModel->getDbName());
77 $savedFieldType = $this->get($this->fieldModel->getDbName().'_type');
78 $savedFieldId = $this->get($this->fieldModel->getDbName().'_id');
79 $value = self::objectsToIds($this->args['value'] ?? null);
80
81 // check is value is changed, if not, do nothing and return true
82 if ($savedFieldValue == $value) {

#5 advanced-custom-post-type/src/Integrations/Divi/includes/ACPT_Divi_Dynamic_Content_Tags.php:284

  • Error complexity.function

    ACPT_Divi_Dynamic_Content_Tags::renderField has a cyclomatic complexity of 178, untestable risk (above 10): each of its 178 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    ACPT_Divi_Dynamic_Content_Tags::renderField has 626 lines in its body, above 100

  • Warning naming.inconsistent_style

    method `renderField` is camelCase, while most methods in this file are snake_case (5 of 9 names); mixed styles make code harder to scan

284 private function renderField(
285 string $fieldType,
286 $val,
287 ?string $pfx,
288 ?string $sfx,
289 string $display_as,
290 string $list_style,
291 string $enable_html,
292 ?string $date_format,
293 ?string $custom_date_format,

#6 advanced-custom-post-type/src/Core/Generators/Table/TableRecordPageGenerator.php:1174

  • Error complexity.function

    TableRecordPageGenerator::locationRuleOptions has a cyclomatic complexity of 152, untestable risk (above 10): each of its 152 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    TableRecordPageGenerator::locationRuleOptions has 446 lines in its body, above 100

1174 protected function locationRuleOptions(array $location = [], string $ruleKey = ''): string
1175 {
1176 $selectedKey = $ruleKey;
1177
1178 $postTypes = [];
1179 $taxonomies = [];
1180 $optionPages = [];
1181 $mediaFormats = [];
1182 $userIds = [];
1183 $valueless = [];

#7 advanced-custom-post-type/src/Core/CQRS/Query/FetchMetaFieldValueQuery.php:30

  • Error complexity.function

    FetchMetaFieldValueQuery::execute has a cyclomatic complexity of 141, untestable risk (above 10): each of its 141 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    FetchMetaFieldValueQuery::execute has 699 lines in its body, above 100

30 public function execute()
31 {
32 // Prevent any error if one of those functions is undefined:
33 if (!function_exists('get_user_by')) {
34 include_once(ABSPATH . 'wp-includes/pluggable.php');
35 }
36
37 if (!function_exists('get_term')) {
38 include_once(ABSPATH . 'wp-includes/taxonomy.php');
39 }

#8 advanced-custom-post-type/src/Utils/Checker/FieldVisibilityChecker.php:99

  • Error complexity.function

    FieldVisibilityChecker::returnTrueOrFalseForALogicBlock has a cyclomatic complexity of 137, untestable risk (above 10): each of its 137 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    FieldVisibilityChecker::returnTrueOrFalseForALogicBlock has 477 lines in its body, above 100

  • Warning naming.too_long

    method `returnTrueOrFalseForALogicBlock` is 31 characters (limit 30); very long names make code hard to read

99 private static function returnTrueOrFalseForALogicBlock(
100 $elementId,
101 string $belongsTo,
102 MetaFieldModel $metaBoxFieldModel,
103 array $conditions,
104 array $liveData = [],
105 ?int $fieldIndex = null,
106 ?string $blockName = null,
107 ?int $blockIndex = null
108 ): bool {

#9 advanced-custom-post-type/src/Core/Generators/CustomPostType/CustomPostTypeAdminColumnsGenerator.php:37

  • Error complexity.function

    CustomPostTypeAdminColumnsGenerator::addColumns has a cyclomatic complexity of 131, untestable risk (above 10): each of its 131 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    CustomPostTypeAdminColumnsGenerator::addColumns has 523 lines in its body, above 100

37 public static function addColumns($postTypeModel): void
38 {
39 $postTypeName = ($postTypeModel instanceof CustomPostTypeModel) ? $postTypeModel->getName() : $postTypeModel;
40
41 $manageEditAction = 'manage_edit-'.$postTypeName.'_columns';
42 $manageEditSortAction = 'manage_edit-'.$postTypeName.'_sortable_columns';
43 $customColumnsAction = 'manage_'.$postTypeName.'_posts_custom_column';
44 $bulkActionsAction = 'bulk_actions-edit-'.$postTypeName;
45
46 // Specific fix for Media attachments

#10 advanced-custom-post-type/src/Core/Helper/CCTFieldShape.php:263

  • Error complexity.function

    CCTFieldShape::coerce has a cyclomatic complexity of 130, untestable risk (above 10): each of its 130 paths needs its own test, which makes it hard to follow and to change safely

  • Error length.function

    CCTFieldShape::coerce has 281 lines in its body, above 100

263 public static function coerce($oldValue, string $targetUiType)
264 {
265 if ($oldValue === null || $oldValue === '') {
266 return null;
267 }
268
269 // Decode JSON strings
270 if (is_string($oldValue) && self::looksLikeJson($oldValue)) {
271 $oldValue = json_decode($oldValue, true);
272 }

Full engine output

All 3,480 findings, plus 8 suppressed by a phpcs comment, exactly as the engine printed them: wordpress-acpt.txt (plain text).