tourze / wechat-official-account-menu-bundle
微信公众号-自定义菜单
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/tourze/wechat-official-account-menu-bundle
Requires
- php: ^8.1
- doctrine/collections: ^2.3
- doctrine/dbal: ^4.0
- doctrine/doctrine-bundle: ^2.13
- doctrine/orm: ^3.0
- doctrine/persistence: ^3.1 || ^4
- symfony/config: ^6.4
- symfony/dependency-injection: ^6.4
- symfony/doctrine-bridge: ^6.4
- symfony/event-dispatcher: ^6.4
- symfony/framework-bundle: ^6.4
- symfony/http-kernel: ^6.4
- symfony/security-http: ^6.4
- symfony/yaml: ^6.4 || ^7.1
- tourze/bundle-dependency: 0.0.*
- tourze/doctrine-indexed-bundle: 0.0.*
- tourze/doctrine-snowflake-bundle: 0.1.*
- tourze/doctrine-timestamp-bundle: 0.0.*
- tourze/doctrine-user-bundle: 0.0.*
- tourze/easy-admin-attribute: 0.1.*
- tourze/enum-extra: 0.1.*
- tourze/json-rpc-core: 0.0.*
- tourze/symfony-integration-test-kernel: 0.0.*
- tourze/wechat-official-account-bundle: 0.1.*
Requires (Dev)
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0
This package is auto-updated.
Last update: 2025-11-02 05:58:37 UTC
README
[]
(https://packagist.org/packages/tourze/wechat-official-account-menu-bundle)
A comprehensive WeChat Official Account custom menu management bundle for Symfony, providing complete menu management functionality with version control and visual editing support.
Table of Contents
- Features
- Installation
- Requirements
- Dependencies
- Usage
- Advanced Usage
- Data Models
- Events
- Configuration
- Security
- Limitations
- Error Handling
- Roadmap
- License
- References
Features
- 📋 Menu Management: Create, edit, delete, sort, and copy menus
- 📦 Version Control: Menu versioning, publishing, rollback, and comparison
- ✅ Menu Validation: Automatic validation against WeChat restrictions
- 🔄 WeChat API Integration: Automatic menu synchronization to WeChat servers
- 🎯 Personalized Menus: Support for creating and managing personalized menus
- 🌲 Tree Structure: Support for up to two-level menu hierarchy
- 🚀 Performance Optimization: Enable/disable menus, batch operations
Installation
composer require tourze/wechat-official-account-menu-bundle
Requirements
- PHP 8.1 or higher
- Symfony 6.4 or higher
- Doctrine ORM
- Valid WeChat Official Account
Dependencies
This bundle requires the following packages:
symfony/framework-bundle- Core Symfony frameworkdoctrine/doctrine-bundle- Database abstraction layertourze/wechat-official-account-bundle- WeChat API integrationsymfony/validator- Data validationsymfony/serializer- Object serialization
Usage
1. Menu Management
Creating Menus
use WechatOfficialAccountMenuBundle\Service\MenuService; // Create top-level menu $menuData = [ 'name' => 'Products', 'type' => MenuType::VIEW, 'url' => 'https://example.com/products', 'position' => 0, 'enabled' => true, ]; $menuButton = $menuService->createMenuButton($account, $menuData); // Create sub-menu $subMenuData = [ 'name' => 'Product Details', 'type' => MenuType::VIEW, 'url' => 'https://example.com/product/detail', 'parent' => $parentMenuButton, ]; $subMenuButton = $menuService->createMenuButton($account, $subMenuData);
Updating Menus
$menuService->updateMenuButton($menuButton, [ 'name' => 'New Products', 'url' => 'https://example.com/new-products', ]);
Menu Sorting
$positions = [ 'button_id_1' => 0, 'button_id_2' => 1, 'button_id_3' => 2, ]; $menuService->updateMenuPositions($positions);
2. Version Management
Creating Versions
use WechatOfficialAccountMenuBundle\Service\MenuVersionService; // Create version from current menu $version = $menuVersionService->createVersion( $account, '2024 Spring Festival Menu' ); // Create from existing version $newVersion = $menuVersionService->createVersion( $account, 'Adjusted from Spring Festival version', $existingVersion );
Publishing Versions
try { $menuVersionService->publishVersion($version); echo "Menu published successfully!"; } catch (MenuVersionException $e) { echo "Publishing failed: " . $e->getMessage(); }
Version Rollback
$rollbackVersion = $menuVersionService->rollbackToVersion($oldVersion);
Version Comparison
$changes = $menuVersionService->compareVersions($version1, $version2); // Returns: added, removed, modified
3. API Endpoints
All endpoints return JSON format data.
Menu Version API
GET /admin/menu/version/{id}/menus- Get version menusPOST /admin/menu/version/{id}/menu- Create menu in versionPUT /admin/menu/version/{id}/menu/{menuId}- Update menu in versionDELETE /admin/menu/version/{id}/menu/{menuId}- Delete menu from versionPOST /admin/menu/version/{id}/positions- Update menu positionsPOST /admin/menu/version/{id}/from-current- Create version from current menu
4. Menu Types
Supported menu types (MenuType):
NONE- No action (for parent menus)VIEW- Jump to URLCLICK- Click push eventMINI_PROGRAM- Mini ProgramSCAN_CODE_PUSH- Scan code push eventSCAN_CODE_WAIT_MSG- Scan code with promptPIC_SYS_PHOTO- System photoPIC_PHOTO_ALBUM- Photo albumPIC_WEIXIN- WeChat albumLOCATION_SELECT- Send location
5. Visual Editor Integration
This package provides complete data interface support for frontend visual editors, including:
- Tree menu structure data
- Drag-and-drop sorting support
- Real-time preview
- Version management interface
- Menu validation prompts
Advanced Usage
Personalized Menus
Create conditional menus based on user attributes:
use WechatOfficialAccountMenuBundle\Service\WechatMenuApiService; // Create personalized menu for specific user groups $personalizedMenu = [ 'button' => $menuButtons, 'matchrule' => [ 'tag_id' => '101', // User tag ID 'sex' => '1', // Gender: 1=Male, 2=Female 'country' => 'CN', // Country 'province' => 'Guangdong', // Province 'city' => 'Guangzhou', // City 'client_platform_type' => '1', // Platform: 1=iOS, 2=Android, 3=Others 'language' => 'zh_CN' // Language ] ]; $wechatMenuApiService->addConditionalMenu($account, $personalizedMenu);
Batch Operations
Efficiently manage multiple menus:
// Batch create menus $menuBatchData = [ ['name' => 'Menu 1', 'type' => MenuType::VIEW, 'url' => 'https://example.com/1'], ['name' => 'Menu 2', 'type' => MenuType::VIEW, 'url' => 'https://example.com/2'], ['name' => 'Menu 3', 'type' => MenuType::CLICK, 'key' => 'MENU_3_KEY'], ]; foreach ($menuBatchData as $index => $data) { $data['position'] = $index; $menuService->createMenuButton($account, $data); } // Batch enable/disable menus $menuService->batchUpdateStatus($menuIds, true); // Enable all $menuService->batchUpdateStatus($menuIds, false); // Disable all
Menu Analytics and Monitoring
Track menu performance:
// Get menu click statistics (requires custom implementation) $stats = $menuService->getMenuClickStats($account, $startDate, $endDate); // Monitor menu synchronization status $syncStatus = $wechatMenuApiService->getCurrentMenuInfo($account); if ($syncStatus['is_menu_open'] === 1) { echo "Menu is enabled on WeChat"; }
Error Recovery
Handle failed operations gracefully:
use WechatOfficialAccountMenuBundle\Exception\WechatApiException; try { $menuVersionService->publishVersion($version); } catch (WechatApiException $e) { // Log the error $logger->error('Menu publish failed', [ 'error_code' => $e->getErrorCode(), 'error_msg' => $e->getMessage(), 'version_id' => $version->getId() ]); // Attempt recovery if ($e->getErrorCode() === 48001) { // API unauthorized // Refresh access token and retry $accessTokenService->refreshToken($account); $menuVersionService->publishVersion($version); } }
Data Models
MenuButton (Menu Button)
- Supports tree structure (up to two levels)
- Includes sorting and enable/disable status
- Automatic menu structure validation
MenuVersion (Menu Version)
- Auto-generated version numbers
- Status: draft, published, archived
- Saves menu snapshots
- Records publishing history
MenuButtonVersion (Versioned Menu Button)
- Associated with specific versions
- Maintains original button ID for comparison
Events
MenuVersionCreatedEvent- Triggered when version is createdMenuVersionPublishedEvent- Triggered when version is published
Configuration
Configure in config/packages/wechat_official_account_menu.yaml:
# No special configuration needed currently, all services are auto-registered
Security
Access Control
- Always validate user permissions before menu operations
- Implement proper role-based access control for menu management
- Use CSRF protection for all menu modification forms
Data Validation
- All input data is validated using Symfony Validator
- Menu structures are validated against WeChat API requirements
- URL validation prevents malicious redirects
WeChat API Security
- Store WeChat access tokens securely
- Implement rate limiting for API calls
- Use HTTPS for all WeChat API communications
Recommended Practices
// Always validate account ownership if ($menu->getAccount()->getId() !== $currentUserAccountId) { throw new AccessDeniedException('Insufficient permissions'); } // Validate URLs before setting if (!filter_var($url, FILTER_VALIDATE_URL)) { throw new InvalidArgumentException('Invalid URL format'); }
Limitations
According to WeChat official documentation:
- Maximum 3 top-level menus
- Maximum 5 sub-menus per top-level menu
- Menu name maximum 60 characters
- Key value maximum 128 characters
- URL maximum 1024 characters
Error Handling
use WechatOfficialAccountMenuBundle\Exception\MenuValidationException; use WechatOfficialAccountMenuBundle\Exception\MenuVersionException; use WechatOfficialAccountMenuBundle\Exception\WechatApiException; try { // Menu operations } catch (MenuValidationException $e) { // Menu validation failed } catch (MenuVersionException $e) { // Version operation failed } catch (WechatApiException $e) { // WeChat API call failed $errorCode = $e->getErrorCode(); }
Roadmap
- Support for media material menus
- Support for rich media message menus
- Batch import/export functionality
- Menu usage statistics
- More personalized menu conditions
Contributing
We welcome contributions to this project! Here's how you can help:
Reporting Issues
- Use the GitHub issue tracker to report bugs
- Include as much detail as possible (PHP version, Symfony version, error messages)
- Provide a minimal code example that reproduces the issue
Contributing Code
- Fork the repository and create a feature branch
- Follow the existing code style and conventions
- Write tests for new functionality
- Ensure all tests pass before submitting a PR
- Update documentation if needed
Code Standards
- Follow PSR-12 coding standards
- Use PHP 8.1+ features where appropriate
- Maintain backward compatibility when possible
- Add type declarations for all method parameters and return values
Testing
- All new features must include unit tests
- Integration tests are required for services and repositories
- Maintain test coverage above 80%
License
This project is licensed under the MIT License - see the LICENSE file for details.
References
- [WeChat Official Documentation - Custom Menu Creation] (https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html)
- [WeChat Official Documentation - Personalized Menu Interface] (https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Personalized_menu_interface.html)
- [WeChat Official Documentation - Get Custom Menu Configuration] (https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Getting_Custom_Menu_Configurations.html)