- Timestamp:
- 10/14/2026 04:54:36 PM (2 weeks ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
formidable/trunk/classes/controllers/FrmAddonsController.php
r3688662 r3746820 19 19 * @var string 20 20 */ 21 private static $request_addon_url;22 23 /**24 * @var string25 */26 21 protected static $plugin; 27 22 … … 38 33 return; 39 34 } 40 41 self::$request_addon_url = 'https://connect.formidableforms.com/add-on-request/';42 35 43 36 add_action( 'admin_enqueue_scripts', self::class . '::enqueue_assets', 15 ); … … 88 81 private static function get_js_variables() { 89 82 return array( 90 'proIsIncluded' => FrmAppHelper::pro_is_included(), 91 'addonRequestURL' => self::$request_addon_url, 83 'proIsIncluded' => FrmAppHelper::pro_is_included(), 92 84 ); 93 85 } … … 139 131 FrmAppHelper::include_svg(); 140 132 141 $view_path = FrmAppHelper::plugin_path() . '/classes/views/addons/'; 142 $installed_addons = apply_filters( 'frm_installed_addons', array() ); 143 $addons = self::get_api_addons(); 144 $errors = array(); 145 $license_type = ''; 146 $request_addon_url = self::$request_addon_url; 133 $view_path = FrmAppHelper::plugin_path() . '/classes/views/addons/'; 134 $installed_addons = apply_filters( 'frm_installed_addons', array() ); 135 $addons = self::get_api_addons(); 136 $errors = array(); 137 $license_type = ''; 147 138 148 139 if ( isset( $addons['error'] ) ) { … … 164 155 ), 165 156 ); 166 $addons = $pro + $addons; 157 $addons = $pro + self::get_built_in_addons() + $addons; 158 $addons = self::move_addon_after( $addons, 'stripe', 'stripe-payments' ); 167 159 self::prepare_addons( $addons ); 168 160 … … 173 165 174 166 include $view_path . 'index.php'; 167 } 168 169 /** 170 * Get the payment gateways that ship inside Lite so they render as active add-on cards. 171 * 172 * These are not installable plugins. The `built_in` flag gives them an active 173 * status, keeps them unlocked, and limits the card footer to the docs link. 174 * 175 * @since 7.0 176 * 177 * @return array<string,array<string,mixed>> 178 */ 179 protected static function get_built_in_addons() { 180 return array( 181 'stripe-payments' => array( 182 'slug' => 'stripe-payments', 183 'title' => 'Stripe', 184 'built_in' => true, 185 'categories' => array( 'Ecommerce' ), 186 'docs' => 'knowledgebase/stripe/', 187 'excerpt' => 'Any Formidable forms on your site can accept credit card payments without users ever leaving your site.', 188 ), 189 'square-payments' => array( 190 'slug' => 'square-payments', 191 'title' => 'Square', 192 'built_in' => true, 193 'categories' => array( 'Ecommerce' ), 194 'docs' => 'knowledgebase/square/', 195 'excerpt' => 'Take one-time payments with Square, with support for Apple Pay and Google Pay.', 196 ), 197 'paypal-commerce' => array( 198 'slug' => 'paypal-commerce', 199 'title' => 'PayPal Commerce', 200 'built_in' => true, 201 'categories' => array( 'Ecommerce' ), 202 'docs' => 'knowledgebase/formidable-paypal/', 203 'excerpt' => 'Collect instant payments and recurring payments with PayPal Commerce on any Formidable form.', 204 ), 205 ); 206 } 207 208 /** 209 * Move an add-on to display immediately after another one. 210 * 211 * Used to keep "Stripe Pro" next to the always-on "Stripe" card, since 212 * the API add-ons are otherwise appended after all built-in gateways. 213 * Add-ons are matched by their normalized slug rather than their array 214 * key, because API-sourced add-ons are keyed by a numeric download id 215 * with the real slug in their `slug` field. 216 * 217 * @since 7.0 218 * 219 * @param array<int|string,array<string,mixed>> $addons The full addons array, keyed by slug or id. 220 * @param string $slug Normalized slug of the add-on to move. 221 * @param string $after_slug Normalized slug of the add-on it should follow. 222 * 223 * @return array<int|string,array<string,mixed>> 224 */ 225 protected static function move_addon_after( $addons, $slug, $after_slug ) { 226 $target_id = self::find_addon_id_by_slug( $addons, $slug ); 227 $after_id = self::find_addon_id_by_slug( $addons, $after_slug ); 228 229 if ( null === $target_id || null === $after_id ) { 230 return $addons; 231 } 232 233 $addon = $addons[ $target_id ]; 234 unset( $addons[ $target_id ] ); 235 236 $reordered = array(); 237 238 foreach ( $addons as $id => $value ) { 239 $reordered[ $id ] = $value; 240 241 if ( $id === $after_id ) { 242 $reordered[ $target_id ] = $addon; 243 } 244 } 245 246 return $reordered; 247 } 248 249 /** 250 * Find an add-on's array key by its normalized slug. 251 * 252 * Mirrors the slug derivation in prepare_addons(): a numeric key names 253 * an API-sourced add-on whose real slug lives in its `slug` field, 254 * while a string key (built-in gateways, the fallback list) already is 255 * the slug. 256 * 257 * @since 7.0 258 * 259 * @param array<int|string,array<string,mixed>> $addons The full addons array, keyed by slug or id. 260 * @param string $slug Normalized slug to find. 261 * 262 * @return int|string|null 263 */ 264 protected static function find_addon_id_by_slug( $addons, $slug ) { 265 foreach ( $addons as $id => $addon ) { 266 $addon_slug = is_numeric( $id ) 267 ? str_replace( array( '-wordpress-plugin', '-wordpress' ), '', $addon['slug'] ) 268 : $id; 269 270 if ( $addon_slug === $slug ) { 271 return $id; 272 } 273 } 274 275 return null; 276 } 277 278 /** 279 * Override how an add-on is presented on the Add-Ons page. 280 * 281 * The built-in gateways cover base payment processing, so the add-ons that 282 * extend them are presented as their Pro/Legacy tiers until the API reflects 283 * it. Names only — the add-ons keep their original excerpts. 284 * 285 * @since 7.0 286 * 287 * @param array $addon The addon array that will be modified by reference. 288 * @param string $slug The addon slug. 289 * 290 * @return void 291 */ 292 protected static function override_addon_display( &$addon, $slug ) { 293 $overrides = array( 294 'stripe' => array( 295 'display_name' => 'Stripe Pro', 296 ), 297 'paypal-standard' => array( 298 'display_name' => 'PayPal Legacy', 299 ), 300 ); 301 302 if ( isset( $overrides[ $slug ] ) ) { 303 $addon = array_merge( $addon, $overrides[ $slug ] ); 304 } 175 305 } 176 306 … … 977 1107 } 978 1108 1109 self::override_addon_display( $addon, $slug ); 1110 979 1111 $addon['installed'] = self::is_installed( $file_name ); 980 1112 … … 1079 1211 */ 1080 1212 protected static function set_addon_status( &$addon ) { 1081 if ( ! empty( $addon['activate_url'] ) ) { 1213 if ( ! empty( $addon['built_in'] ) ) { 1214 $addon['status'] = array( 1215 'type' => 'active', 1216 'label' => __( 'Active', 'formidable' ), 1217 ); 1218 } elseif ( ! empty( $addon['activate_url'] ) ) { 1082 1219 $addon['status'] = array( 1083 1220 'type' => 'installed', … … 1094 1231 'label' => __( 'Not Installed', 'formidable' ), 1095 1232 ); 1096 } 1233 }//end if 1097 1234 } 1098 1235 … … 1458 1595 */ 1459 1596 public static function connect_link() { 1597 $user_id = get_current_user_id(); 1598 1599 if ( ! self::user_can_connect_account( $user_id ) ) { 1600 return ''; 1601 } 1602 1460 1603 $auth = get_option( 'frm_connect_token' ); 1461 1604 1462 if ( ! $auth ) {1463 $auth = hash( 'sha512', wp_ rand() );1605 if ( ! $auth || ! self::user_can_connect_account( (int) get_option( 'frm_connect_user' ) ) ) { 1606 $auth = hash( 'sha512', wp_generate_password( 64, true, true ) ); 1464 1607 update_option( 'frm_connect_token', $auth, false ); 1608 update_option( 'frm_connect_user', $user_id, false ); 1465 1609 } 1466 1610 … … 1481 1625 1482 1626 /** 1627 * Check whether a user can authorize the account connection. 1628 * 1629 * @since 7.0 1630 * 1631 * @param int $user_id The user authorizing the account connection. 1632 * 1633 * @return bool 1634 */ 1635 private static function user_can_connect_account( $user_id ) { 1636 if ( ! $user_id || ! user_can( $user_id, 'activate_plugins' ) ) { 1637 return false; 1638 } 1639 1640 return user_can( $user_id, 'install_plugins' ) || FrmAppHelper::pro_is_included() || self::is_installed( 'formidable-pro/formidable-pro.php' ); 1641 } 1642 1643 /** 1483 1644 * Check the auth value for install permission. 1484 1645 * … … 1488 1649 */ 1489 1650 public static function can_install_addon_api() { 1651 // The external callback uses the permissions of the user who initiated the connection. 1652 if ( ! self::user_can_connect_account( (int) get_option( 'frm_connect_user' ) ) ) { 1653 return false; 1654 } 1655 1490 1656 // Verify params present (auth & download link). 1491 1657 $post_auth = FrmAppHelper::get_param( 'token', '', 'request', 'sanitize_text_field' ); … … 1493 1659 1494 1660 // The download link is not required if already installed. 1495 $is_installed = FrmAppHelper::pro_is_included() ;1661 $is_installed = FrmAppHelper::pro_is_included() || self::is_installed( 'formidable-pro/formidable-pro.php' ); 1496 1662 $file_missing = ! $is_installed && ! $post_url; 1497 1663 … … 1513 1679 */ 1514 1680 public static function install_addon_api() { 1515 self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' ); 1681 self::$plugin = FrmAppHelper::get_param( 'file_url', '', 'request', 'esc_url_raw' ); 1682 $can_install_plugins = user_can( (int) get_option( 'frm_connect_user' ), 'install_plugins' ); 1516 1683 1517 1684 // Delete so cannot replay. 1518 1685 delete_option( 'frm_connect_token' ); 1686 delete_option( 'frm_connect_user' ); 1519 1687 1520 1688 // It's already installed and active. … … 1522 1690 1523 1691 if ( is_wp_error( $active ) ) { 1692 if ( ! $can_install_plugins ) { 1693 return array( 1694 'success' => false, 1695 'message' => __( 'You do not have permission to install plugins.', 'formidable' ), 1696 ); 1697 } 1698 1524 1699 $response = self::maybe_download_and_activate(); 1525 1700
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)