apiRoot = esc_url_raw(rest_url('give-api/v2/admin/forms')); $this->bannerActionUrl = admin_url('admin-ajax.php?action=givewp_show_onboarding_banner'); $this->tooltipActionUrl = admin_url('admin-ajax.php?action=givewp_show_upgraded_tooltip'); $this->defaultFormActionUrl = admin_url('admin-ajax.php?action=givewp_show_default_form_tooltip'); $this->migrationApiRoot = esc_url_raw(rest_url('give-api/v2/admin/forms/migrate')); $this->apiNonce = wp_create_nonce('wp_rest'); $this->adminUrl = admin_url(); } /** * Register menu item * @since 4.14.0 update permission capability to use facade * @since 4.0.0 set submenu parent to empty string to hide "all forms" from admin menu */ public function register() { remove_submenu_page('edit.php?post_type=give_forms', 'edit.php?post_type=give_forms'); add_submenu_page( '', esc_html__('Donation Forms', 'give'), esc_html__('All Forms', 'give'), UserPermissions::donationForms()->viewCap(), 'give-forms', [$this, 'render'], // Do not change the submenu position unless you have a strong reason. // We use this position value to access this menu data in $submenu to add a custom class. // Check DonationFormsAdminPage::highlightAllFormsMenuItem 0 ); } /** * @since 2.20.0 */ public function highlightAllFormsMenuItem() { global $submenu; $pages = [ '/wp-admin/admin.php?page=give-forms', // Donation main menu page. '/wp-admin/edit.php?post_type=give_forms', // Legacy donation form listing page. ]; if (in_array($_SERVER['REQUEST_URI'], $pages)) { // Add class to highlight 'All Forms' submenu. $submenu['edit.php?post_type=give_forms'][0][4] = add_cssclass( 'current', isset($submenu['edit.php?post_type=give_forms'][0][4]) ? $submenu['edit.php?post_type=give_forms'][0][4] : '' ); } } /** * Load scripts * * @since 3.22.0 Add locale support */ public function loadScripts() { $data = [ 'apiRoot' => $this->apiRoot, 'bannerActionUrl' => $this->bannerActionUrl, 'tooltipActionUrl' => $this->tooltipActionUrl, 'defaultFormActionUrl' => $this->defaultFormActionUrl, 'apiNonce' => $this->apiNonce, 'preload' => $this->preloadDonationForms(), 'authors' => $this->getAuthors(), 'table' => give(DonationFormsListTable::class)->toArray(), 'adminUrl' => $this->adminUrl, 'pluginUrl' => GIVE_PLUGIN_URL, 'showUpgradedTooltip' => !get_user_meta(get_current_user_id(), 'givewp-show-upgraded-tooltip', true), 'showDefaultFormTooltip' => !get_user_meta(get_current_user_id(), 'givewp-show-default-form-tooltip', true), 'supportedAddons' => $this->getSupportedAddons(), 'supportedGateways' => $this->getSupportedGateways(), 'isOptionBasedFormEditorEnabled' => OptionBasedFormEditor::isEnabled(), 'locale' => Language::getLocale(), 'swrConfig' => [ 'revalidateOnFocus' => false ], ]; EnqueueScript::make('give-admin-donation-forms', 'build/assets/dist/js/give-admin-donation-forms.js') ->loadInFooter() ->registerTranslations() ->registerLocalizeData('GiveDonationForms', $data)->enqueue(); wp_enqueue_style( 'give-admin-ui-font', 'https://fonts.googleapis.com/css2?family=Open+Sans:wght@400..700&display=swap', [], null ); wp_enqueue_style('givewp-design-system-foundation'); } /** * Load migration onboarding scripts * @since 3.2.0 * * @return void */ public function loadMigrationScripts() { if ($this->isShowingAddV2FormPage()) { EnqueueScript::make('give-add-v2form', 'build/assets/dist/js/give-add-v2form.js') ->loadInFooter() ->registerTranslations() ->registerLocalizeData('GiveDonationForms', [ 'supportedAddons' => $this->getSupportedAddons(), 'supportedGateways' => $this->getSupportedGateways(), ]) ->enqueue(); wp_enqueue_style('givewp-design-system-foundation'); } if ($this->isShowingEditV2FormPage()) { $formId = (int)$_GET['post']; $campaign = Campaign::findByFormId($formId); $isMigrated = _give_is_form_migrated($formId); $campaignUrl = $campaign ? admin_url('edit.php?post_type=give_forms&page=give-campaigns&id=' . $campaign->id) : ''; /** * Filters the campaign URL displayed on the v2 form edit screen. * Allows add-ons (e.g., P2P) to provide their own campaign URL. * * @since 4.14.2 * * @param string $campaignUrl The campaign admin URL, or empty string if not found. * @param int $formId The donation form ID being edited. */ $campaignUrl = apply_filters('givewp_form_builder_campaign_url', $campaignUrl, $formId); $migratedFormUrl = ''; if ($isMigrated) { $v3FormId = (new GetMigratedFormId)($formId); if ($v3FormId) { $migratedFormUrl = add_query_arg([ 'post_type' => 'give_forms', 'page' => 'givewp-form-builder', 'donationFormID' => $v3FormId, 'showTransfer' => '1', ], admin_url('edit.php')); } } EnqueueScript::make('give-edit-v2form', 'build/assets/dist/js/give-edit-v2form.js') ->loadInFooter() ->registerTranslations() ->registerLocalizeData('GiveDonationForms', [ 'supportedAddons' => $this->getSupportedAddons(), 'supportedGateways' => $this->getSupportedGateways(), 'migrationApiRoot' => $this->migrationApiRoot, 'apiNonce' => $this->apiNonce, 'isMigrated' => $isMigrated, 'migratedFormUrl' => $migratedFormUrl, 'campaignUrl' => $campaignUrl, ]) ->enqueue(); wp_enqueue_style('givewp-design-system-foundation'); } } /** * Get first page of results from REST API to display as initial table data * * @since 4.0.0 Add campaignId parameter on campaigns page * @since 2.20.0 * @return array */ private function preloadDonationForms() { $queryParameters = [ 'page' => 1, 'perPage' => 30, ]; if (CampaignsAdminPage::isShowingDetailsPage()) { $queryParameters['campaignId'] = isset($_GET['id']) ? absint($_GET['id']) : null; } $request = WP_REST_Request::from_url( add_query_arg( $queryParameters, $this->apiRoot ) ); return rest_do_request($request)->get_data(); } /** * Get a list of author user IDs and names * @since 2.20.0 */ public function getAuthors() { $author_users = get_users([ 'role__in' => ['author', 'administrator'], ]); return array_map(function ($user) { return [ 'id' => $user->ID, 'name' => $user->display_name, ]; }, $author_users); } /** * Render admin page */ public function render() { echo '
'; } /** * Render the migration guide box on the old edit donation form page * * @since 3.0.0 * * @param WP_Post $post * * @return void */ public function renderMigrationGuideBox(WP_Post $post) { if ($post->post_type === 'give_forms') { echo '
'; } } /** * Display a button on the old donation forms table that switches to the React view * * @since 2.20.0 */ public function renderReactSwitch() { ?> post_type === 'give_forms'; } /** * Helper function to determine if current page is the add v2 form page * * @since 3.0.0 * * @return bool */ private function isShowingAddV2FormPage(): bool { return !isset($_GET['page']) && isset($_GET['post_type']) && $_GET['post_type'] === 'give_forms'; } /** * Helper function to determine if the current page is the legacy donation forms list page * * @since 2.20.1 */ public static function isShowingLegacyPage(): bool { return isset($_GET['post_type']) && $_GET['post_type'] === 'give_forms' && empty($_GET['page']); } /** * @since 2.20.0 * @return string */ public static function getUrl(): string { return add_query_arg(['page' => 'give-forms'], admin_url('edit.php?post_type=give_forms')); } /** * Get an array of supported addons * * @since 3.14.0 Added support for Razorpay * @since 3.4.2 Added support for Gift Aid * @since 3.3.0 Add support to the Funds and Designations addon * @since 3.0.0 * @return array */ public function getSupportedAddons(): array { $supportedAddons = [ 'Recurring Donation' => class_exists('Give_Recurring'), 'Fee Recovery' => class_exists('Give_Fee_Recovery'), 'Currency Switcher' => class_exists('Give_Currency_Switcher'), 'Form Field Manager' => class_exists('Give_Form_Fields_Manager'), 'Tributes' => class_exists('Give_Tributes'), 'Google Analytics Donation Tracking' => class_exists('Give_Google_Analytics'), 'PDF Receipts' => class_exists('Give_PDF_Receipts'), 'Annual Receipts' => class_exists('Give_Annual_Receipts'), 'Webhooks' => defined('GIVE_WEBHOOKS_VERSION'), 'Email Reports' => defined('GIVE_EMAIL_REPORTS_VERSION'), 'Zapier' => defined('GIVE_ZAPIER_VERSION'), 'Salesforce' => defined('GIVE_SALESFORCE_VERSION'), 'Donation Upsells for WooCommerce' => class_exists('Give_WooCommerce'), 'Constant Contact' => class_exists('Give_Constant_Contact'), 'MailChimp' => class_exists('Give_MailChimp'), 'Manual Donations' => class_exists('Give_Manual_Donations'), 'Funds' => defined('GIVE_FUNDS_ADDON_NAME'), 'Peer-to-Peer' => defined('GIVE_P2P_NAME'), 'Gift Aid' => class_exists('Give_Gift_Aid'), 'Text-to-Give' => defined('GIVE_TEXT_TO_GIVE_ADDON_NAME'), 'Double the Donation' => defined('GIVE_DTD_NAME'), 'Per Form Gateways' => class_exists('Give_Per_Form_Gateways'), 'ConvertKit' => defined('GIVE_CONVERTKIT_VERSION'), 'ActiveCampaign' => class_exists('Give_ActiveCampaign'), 'Razorpay' => class_exists('Give_Razorpay_Gateway'), ]; $output = []; foreach ($supportedAddons as $name => $isInstalled) { if ($isInstalled) { $output[] = $name; } } return $output; } /** * Get an array of supported gateways * * @since 3.0.0 * @return array */ public function getSupportedGateways(): array { $gateways = give_get_payment_gateways(); $supportedGateways = array_intersect_key($gateways, give()->gateways->getPaymentGateways(3)); ksort($supportedGateways); unset($supportedGateways['manual']); return array_map(function ($gateway) { return $gateway['admin_label']; }, $supportedGateways); } }