$addon['status'] = 'missing';
$addon['action'] = 'upgrade';
$addon['page_url'] = $this->default_data( $addon, 'url', '' );
$addon['doc_url'] = $this->default_data( $addon, 'doc', '' );
$nonce = empty( $nonce ) ? wp_create_nonce( 'wpforms-admin' ) : $nonce;
$addon['nonce'] = $nonce;
* @param array|mixed $addon Addon data.
* @param string $key Key.
* @param mixed $default_data Default data.
* @return array|string|mixed
private function default_data( $addon, string $key, $default_data ) {
if ( is_string( $default_data ) ) {
return ! empty( $addon[ $key ] ) ? $addon[ $key ] : $default_data;
if ( is_array( $default_data ) ) {
return ! empty( $addon[ $key ] ) ? (array) $addon[ $key ] : $default_data;
return $addon[ $key ] ?? '';
private function populate_addons_data() {
foreach ( $this->addons as $addon ) {
$this->addons_text_domains[] = $addon['slug'];
$this->addons_titles[] = 'WPForms ' . str_replace( ' Addon', '', $addon['title'] );
* This filter allows us to prevent empty translations from being returned
* on the `plugins` page for addon name and description.
* @param string|mixed $translation Translated text.
* @param string|mixed $text Text to translate.
* @param string|mixed $domain Text domain.
* @return string Translated text.
public function filter_gettext( $translation, $text, $domain ): string {
$translation = (string) $translation;
$domain = (string) $domain;
if ( ! in_array( $domain, $this->addons_text_domains, true ) ) {
// Prevent empty translations from being returned and don't translate addon names.
if ( ! trim( $translation ) || in_array( $text, $this->addons_titles, true ) ) {