WP VCard Generator
WordPress plugin that generates downloadable vCard (.vcf) contact files for employees from ACF fields. Includes an AJAX generate button, a 12-hour WP-Cron job, bilingual (FR/EN) job titles and security hardening (nonces, capability checks, vCard escaping).
★ 0stars
0forks
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/leadermed/vcard/archive/refs/heads/main.zipWordPress plugin that generates downloadable vCard (.vcf) contact files for employees from ACF fields.
Features
- "Générer une VCARD" button on the employee edit screen (AJAX).
- WP-Cron job (every 12 hours) that generates the cards that are missing.
- Bilingual (FR/EN) job title, using the translated employee post.
- Output escaped for the vCard 3.0 format.
Requirements
- WordPress 5.2+ and PHP 7.2+
- Advanced Custom Fields
- A custom post type named
employees - Polylang (or WPML) for the bilingual job title. The plugin still works without it.
Installation
- Copy the
wp-vcard-generatorfolder to/wp-content/plugins/. - Activate the plugin in Plugins.
- Open an employee and click Générer une VCARD. The file URL is saved in the
url_de_carteACF field.
Project structure
vcard-generator-plugin.php Main file: hooks, AJAX handler, cron, vCard builder
assets/js/script.js Button behavior (AJAX call with nonce)
assets/css/style.css Admin styles
index.php Prevents directory listing
Design notes
wp_vcard_generate_for_post()holds the generation logic. The AJAX handler and the cron job both call it, so nothing is duplicated and the cron does not depend on$_POST.- Employee data stays in ACF, where the client's team already manages it.
- Generated files are stored in
wp-content/uploads/vcf-cards/and are publicly accessible by URL, because the cards are meant to be shared.
Security
- AJAX requests require a valid nonce and the
edit_postcapability on the employee. post_idis cast withabsint()and must belong to anemployeespost.- Text values are escaped for vCard (line breaks,
;,,,\). URLs are validated withesc_url_raw()and stripped of control characters, which prevents injection of fake vCard properties. - File names are sanitized (
sanitize_file_name()) and include the post ID and language.
Changelog
1.0.2
- Security: nonce and capability checks on the AJAX handler.
- Security: validation of
post_id, escaping of all vCard values, sanitized file names. - Fix: the cron job called the AJAX handler directly and could not work. Logic moved to a shared function.
- Fix: no fatal error if ACF or Polylang is inactive.
- Fix: file URL built from the uploads base URL instead of replacing
ABSPATH. - Fix: no trailing "/" in the title when a translation is missing.
- Change: file names now include the post ID, so cards must be regenerated.
- Change: HTML removed from the vCard note, address formatted as a structured
ADRfield.
1.0.0
- Initial version delivered to the client.
Known limitations / next steps
- Scripts and styles load on every admin page. They should be limited to the employee edit screen.
- Functions are global and prefixed loosely. A namespace or class structure would be safer.
- Strings are not yet translatable (
__()). - The cron event is not cleared on deactivation.
License
GPL v2 or later: https://www.gnu.org/licenses/gpl-2.0.html