PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
3.3.1 V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 All 138 releases
← All changes | includes/Core/Util/Utilities.php +106 -2 2.10.03.3.1 View file →
@@ -7,11 +7,32 @@
7 7 final class Utilities
8 8 {
9 9 public static function isPro()
10 10 {
11 + // IMPORTANT:
12 + // For wp.org (free) distribution we treat "Pro" as "Pro addon is installed/active".
13 + // License enforcement must live inside the Pro addon, not in the free plugin.
14 + return class_exists('BitCode\\BitFormPro\\Plugin');
15 + }
16 +
17 + /**
18 + * Kept for backward compatibility where the free plugin needs to know if a Pro
19 + * license is marked active. Prefer checking license inside the Pro addon.
20 + */
21 + public static function isProLicensed(): bool
22 + {
23 + if (!self::isPro()) {
24 + return false;
25 + }
26 + if (class_exists('BitCode\\BitFormPro\\Core\\Util\\LicenseHelper')) {
27 + return \BitCode\BitFormPro\Core\Util\LicenseHelper::hasValidLicense();
28 + }
11 29 $integrateData = get_option('bitformpro_integrate_key_data');
12 - $isProLicenseActivated = !empty($integrateData) && is_array($integrateData) && 'success' === $integrateData['status'];
13 - return class_exists('BitCode\\BitFormPro\\Plugin') && $isProLicenseActivated;
30 +
31 + return !empty($integrateData)
32 + && is_array($integrateData)
33 + && !empty($integrateData['status'])
34 + && 'success' === $integrateData['status'];
14 35 }
15 36
16 37 public static function getRealPath($dir, $name)
17 38 {
@@ -67,8 +88,35 @@
67 88
68 89 return $css;
69 90 }
70 91
92 + public static function convertToCSS(array $styles): string
93 + {
94 + $css = '';
95 +
96 + foreach ($styles as $selector => $properties) {
97 + $css .= "$selector{";
98 +
99 + // Check if the properties are an array, meaning it's a nested rule (e.g., media queries, keyframes)
100 + if (is_array($properties)) {
101 + // If it's a nested array (media query or keyframe), recursively handle it
102 + foreach ($properties as $property => $value) {
103 + if (is_array($value)) {
104 + // Recursively process nested arrays (media queries, keyframes, etc.)
105 + $css .= self::convertToCSS([$property => $value]);
106 + } else {
107 + // Regular CSS property
108 + $css .= "$property:$value;";
109 + }
110 + }
111 + }
112 +
113 + $css .= '}';
114 + }
115 +
116 + return $css;
117 + }
118 +
71 119 public static function appendCSS($formId, $css, $mode = 'a')
72 120 {
73 121 $fileName = '';
74 122 $path = '';
@@ -76,6 +124,62 @@
76 124 $fileName = "bitform-{$formId}.css";
77 125 Helpers::saveFile($path, $fileName, $css, $mode);
78 126 $fileName = "bitform-{$formId}-formid.css";
79 127 Helpers::saveFile($path, $fileName, $css, $mode);
128 + }
129 +
130 + /**
131 + * First row of a Model/get() style result, or null when the lookup failed
132 + * (WP_Error), returned an empty set, or has no index 0. Prevents
133 + * "Attempt to read property on null" when dereferencing $result[0]->col.
134 + *
135 + * @param mixed $result
136 + * @return object|null
137 + */
138 + public static function firstRow($result)
139 + {
140 + if (is_wp_error($result) || empty($result) || !isset($result[0])) {
141 + return null;
142 + }
143 + return $result[0];
144 + }
145 +
146 + /**
147 + * Decode a JSON string to an object, guaranteed to return object|null so
148 + * downstream `$obj->prop ?? default` reads never emit an undefined-property
149 + * warning. Returns null for non-strings, empty strings and malformed JSON.
150 + *
151 + * @param mixed $json
152 + * @return object|null
153 + */
154 + public static function jsonObj($json)
155 + {
156 + if (!is_string($json) || '' === $json) {
157 + return null;
158 + }
159 + $decoded = json_decode($json);
160 + return is_object($decoded) ? $decoded : null;
161 + }
162 +
163 + /**
164 + * Hardened hosts disable ignore_user_abort in php.ini; PHP 8 fatals on the call instead of warning.
165 + *
166 + * @param bool $ignore
167 + * @return void
168 + */
169 + public static function ignoreUserAbort($ignore = true)
170 + {
171 + if (\function_exists('ignore_user_abort')) {
172 + \ignore_user_abort($ignore);
173 + }
174 + }
175 +
176 + public static function duplicateDbTable($oldTableName, $newTableName)
177 + {
178 + global $wpdb;
179 + $oldTable = "{$wpdb->prefix}bitforms_{$oldTableName}";
180 + $newTable = "{$wpdb->prefix}bitforms_{$newTableName}";
181 + // Schema operation: table name interpolation only (no user input). $wpdb->prepare() cannot parameterize DDL statements.
182 + $wpdb->query("CREATE TABLE IF NOT EXISTS `{$newTable}` LIKE `{$oldTable}`");
183 + $wpdb->query("INSERT INTO `{$newTable}` SELECT * FROM `{$oldTable}`");
80 184 }
81 185 }