Listing Co-Owners for Listeo: Developer Guide
Developer notes for safe overrides, permissions, data ownership, UI integration, testing, and support workflows.
Do not bypass license-gated initialization, override license classes, fake license status, replace updater callbacks, or remove account/domain checks. Developer customization starts after the plugin has been legitimately activated and initialized.
Scope
This guide is for developers extending Listing Co-Owners for Listeo in a child theme, site plugin, or mu-plugin. Every customization must preserve server-side authorization, nonces, ownership checks, and listing boundaries.
Important files
| File | Responsibility |
|---|---|
listing-co-owners-for-listeo.php | Bootstrap, constants, activation defaults, Listeo detection, class loading, update hooks. |
includes/class-lcol-capabilities.php | Capability registry, presets, labels, groups, invite exclusions, form section mapping. |
includes/class-lcol-permissions.php | Central permission checks, Listeo edit checks, dashboard actions, reviews, form filtering. |
includes/class-lcol-team.php | Per-listing team storage and member add/update/remove operations. |
includes/class-lcol-invites.php | Invite table, invite creation, email delivery, accept-link flow. |
includes/class-lcol-query.php | Expands My Listings, reviews, and bookings/calendar queries for assigned users. |
includes/class-lcol-ajax.php | Team panel, invites, member changes, user search, admin saves. |
templates/frontend-team-panel.php | AJAX-rendered team management panel. |
Storage
_lcol_team: current team data structure._lcol_assigned_owners: legacy assigned owners meta kept in sync._lcol_created_by: creator fallback permissions.wp_lcol_invites: invite table with listing ID, email, role, permissions JSON, token, inviter, status, and timestamps.
Permission model
Use LCOL_Permissions::user_can($listing_id, $cap, $user_id) as the central check. Administrators with manage_options pass. Primary owners receive the primary owner capability set. Team members receive capabilities from their stored role and permissions.
Supported filters
| Filter | Use |
|---|---|
lcol_capabilities | Add or adjust capability metadata. Add enforcement wherever the new capability is used. |
lcol_capability_presets | Change manager/editor/support/custom presets. |
lcol_capability_group_labels | Change permission group labels. |
lcol_capability_group_descriptions | Change group help text. |
lcol_invite_excluded_caps | Hide sensitive capabilities from the invite UI. |
lcol_submit_section_permission_map | Map Listeo submit form sections to co-owner capabilities. |
lcol_user_can | Final permission decision filter. Keep listing/user context. |
lcol_assigned_listing_ids_for_user | Adjust listing IDs considered assigned to a user. |
lcol_is_dashboard_context | Load front-end modal/assets on a custom dashboard page. |
Safe overrides
Hide wallet access from invite screens:
add_filter('lcol_invite_excluded_caps', function (array $excluded): array {
$excluded[] = 'wallet';
return array_values(array_unique($excluded));
});
Add a conservative content-only preset:
add_filter('lcol_capability_presets', function (array $presets): array {
$presets['content_assistant'] = [
'label' => 'Content Assistant',
'description' => 'Can update listing content and images only.',
'permissions' => ['view_dashboard', 'edit_description', 'manage_images'],
];
return $presets;
});
Allow assets on a custom dashboard page:
add_filter('lcol_is_dashboard_context', function (bool $is_context): bool {
return $is_context || is_page('partner-dashboard');
});
AJAX actions
Front-end team operations use lcol_team_nonce; admin search/save operations use lcol_admin_nonce. Do not call these actions from public unauthenticated scripts.
lcol_get_team_panellcol_send_invitelcol_cancel_invitelcol_remove_memberlcol_update_memberlcol_search_userslcol_save_listing_owners
Regression checklist
- Primary owner can manage the listing and team.
- Co-owner can see only assigned listings.
- Co-owner can edit only sections allowed by their capabilities.
- Co-owner cannot edit unrelated listings by changing request IDs.
- Removed co-owner immediately loses listing access.
- Pending, accepted, expired, and cancelled invites behave correctly.
- Bookings, reviews, messages, wallet, renew, and delete permissions are tested independently.
- Admin metabox saves keep
_lcol_teamand_lcol_assigned_ownerssynchronized.
Do not customize here
- License activation or update authorization code.
- License-gated class initialization.
- Nonce or capability checks inside AJAX handlers.
- Permission results that grant access without checking the specific listing ID and user ID.
- Direct writes to
_lcol_teamthat bypassLCOL_Team. - SQL or query filters that show private/unassigned listings to co-owners.