ShahiAssist’s modular architecture allows developers to extend functionality by creating custom modules. This guide covers the process of building, registering, and maintaining custom modules.
Module Architecture
Core Components
- Module Base Class:
ShahiAssistModuleBaseprovides common functionality - Module Registry: Manages module loading and initialization
- Autoloader: PSR-4 compliant class loading
- Settings Integration: Automatic settings page generation
- Feature 1
- Feature 2
- Feature 3
- Download and place in
includes/modules/your_module/ - Register in module registry
- Activate in ShahiAssist settings
- Initial release
- WordPress Plugin Development
- PSR-4 Autoloading
- WordPress Coding Standards
- ShahiAssist Module Development Guide
Module Structure
`
includes/modules/your_module/
├── class-your-module.php # Main module class
├── views/ # Template files
│ ├── admin-settings.php
│ ├── frontend-display.php
│ └── …
├── assets/ # CSS/JS files
│ ├── css/
│ └── js/
├── languages/ # Translation files
│ └── your-module.pot
└── README.md # Documentation
`
Creating a Basic Module
Step 1: Create Module Directory
`bash
mkdir -p includes/modules/your_module/views
mkdir -p includes/modules/your_module/assets/css
mkdir -p includes/modules/your_module/assets/js
`
Step 2: Main Module Class
`php
YourModule extends ShahiAssistModuleBase {
/**
* Module ID
*/
protected $moduleid = ‘yourmodule’;
/**
* Module name
*/
protected $module_name = ‘Your Module’;
/**
* Module version
*/
protected $version = ‘1.0.0’;
/**
* Initialize the module
*/
public function init() {
// Hook into WordPress
addaction(‘init’, [$this, ‘registerpost_types’]);
addaction(‘adminmenu’, [$this, ‘addadminmenu’]);
addaction(‘wpenqueuescripts’, [$this, ‘enqueuescripts’]);
// Custom hooks
addaction(‘shahiassistcustomhook’, [$this, ‘custom_function’]);
}
/**
* Register custom post types
*/
public function registerposttypes() {
registerposttype(‘yourcustompost’, [
‘labels’ => [
‘name’ => __(‘Your Posts’, ‘shahi-assist’),
‘singularname’ => _(‘Your Post’, ‘shahi-assist’),
],
‘public’ => true,
‘supports’ => [‘title’, ‘editor’, ‘custom-fields’],
‘showinmenu’ => false,
]);
}
/**
* Add admin menu
*/
public function addadminmenu() {
addsubmenupage(
‘shahi-assist’,
__(‘Your Module’, ‘shahi-assist’),
__(‘Your Module’, ‘shahi-assist’),
‘manage_options’,
‘shahi-assist-your-module’,
[$this, ‘admin_page’]
);
}
/**
* Admin page callback
*/
public function admin_page() {
?>
enqueuestyle(
‘shahi-assist-your-module’,
plugindirurl(FILE) . ‘assets/css/your-module.css’,
[],
$this->version
);
wpenqueuescript(
‘shahi-assist-your-module’,
plugindirurl(FILE) . ‘assets/js/your-module.js’,
[‘jquery’],
$this->version,
true
);
}
/**
* Custom function
*/
public function custom_function() {
// Your custom logic here
doaction(‘yourmodulecustomaction’);
}
/**
* Get module settings
*/
public function get_settings() {
return [
‘enabled’ => [
‘type’ => ‘checkbox’,
‘label’ => __(‘Enable Module’, ‘shahi-assist’),
‘default’ => true,
],
‘api_key’ => [
‘type’ => ‘text’,
‘label’ => __(‘API Key’, ‘shahi-assist’),
‘default’ => ”,
],
];
}
/**
* Activate module
*/
public function activate() {
// Run on module activation
flushrewriterules();
}
/**
* Deactivate module
*/
public function deactivate() {
// Run on module deactivation
flushrewriterules();
}
/**
* Uninstall module
*/
public function uninstall() {
// Clean up on uninstall
deleteoption(‘shahiassistyourmodule_settings’);
}
}
`
Step 3: Register the Module
Add to includes/core/class-module-registry.php:
`php
private function getavailablemodules() {
return [
// … existing modules
‘yourmodule’ => ‘ShahiAssistYour_Module’,
];
}
`
Advanced Module Features
Settings Integration
`php
public function get_settings() {
return [
‘general’ => [
‘title’ => __(‘General Settings’, ‘shahi-assist’),
‘fields’ => [
‘enabled’ => [
‘type’ => ‘checkbox’,
‘label’ => __(‘Enable Module’, ‘shahi-assist’),
‘default’ => true,
],
‘debug_mode’ => [
‘type’ => ‘checkbox’,
‘label’ => __(‘Debug Mode’, ‘shahi-assist’),
‘default’ => false,
],
],
],
‘api’ => [
‘title’ => __(‘API Settings’, ‘shahi-assist’),
‘fields’ => [
‘api_url’ => [
‘type’ => ‘url’,
‘label’ => __(‘API URL’, ‘shahi-assist’),
‘default’ => ”,
],
‘api_key’ => [
‘type’ => ‘password’,
‘label’ => __(‘API Key’, ‘shahi-assist’),
‘default’ => ”,
],
],
],
];
}
`
AJAX Handlers
`php
public function init() {
// … other hooks
addaction(‘wpajaxyourmoduleaction’, [$this, ‘ajaxhandler’]);
addaction(‘wpajaxnoprivyourmoduleaction’, [$this, ‘ajax_handler’]);
}
public function ajax_handler() {
checkajaxreferer(‘yourmodulenonce’, ‘nonce’);
$action = sanitizetextfield($POST[‘subaction’]);
switch ($action) {
case ‘save_data’:
$data = sanitizetextfield($_POST[‘data’]);
updateoption(‘yourmodule_data’, $data);
wpsendjson_success([‘message’ => ‘Data saved’]);
break;
case ‘get_data’:
$data = getoption(‘yourmodule_data’, ”);
wpsendjson_success([‘data’ => $data]);
break;
default:
wpsendjson_error([‘message’ => ‘Invalid action’]);
}
}
`
Custom Post Types
`php
public function registerposttypes() {
$labels = [
‘name’ => __(‘Your Items’, ‘shahi-assist’),
‘singularname’ => _(‘Your Item’, ‘shahi-assist’),
‘addnew’ => _(‘Add New’, ‘shahi-assist’),
‘addnewitem’ => __(‘Add New Item’, ‘shahi-assist’),
‘edititem’ => _(‘Edit Item’, ‘shahi-assist’),
‘newitem’ => _(‘New Item’, ‘shahi-assist’),
‘viewitem’ => _(‘View Item’, ‘shahi-assist’),
‘searchitems’ => _(‘Search Items’, ‘shahi-assist’),
‘notfound’ => _(‘No items found’, ‘shahi-assist’),
‘notfoundintrash’ => _(‘No items found in trash’, ‘shahi-assist’),
];
registerposttype(‘your_item’, [
‘labels’ => $labels,
‘public’ => true,
‘supports’ => [‘title’, ‘editor’, ‘thumbnail’, ‘custom-fields’],
‘menu_icon’ => ‘dashicons-admin-tools’,
‘showinmenu’ => ‘shahi-assist’,
‘capability_type’ => ‘post’,
‘mapmetacap’ => true,
]);
}
`
Custom Taxonomies
`php
public function register_taxonomies() {
registertaxonomy(‘yourcategory’, ‘your_item’, [
‘labels’ => [
‘name’ => __(‘Categories’, ‘shahi-assist’),
‘singularname’ => _(‘Category’, ‘shahi-assist’),
],
‘hierarchical’ => true,
‘showadmincolumn’ => true,
‘rewrite’ => [‘slug’ => ‘your-category’],
]);
}
`
REST API Endpoints
`php
public function registerrestroutes() {
registerrestroute(‘shahi-assist/v1’, ‘/your-module’, [
‘methods’ => ‘GET’,
‘callback’ => [$this, ‘restgetdata’],
‘permissioncallback’ => [$this, ‘restpermissions_check’],
]);
registerrestroute(‘shahi-assist/v1’, ‘/your-module’, [
‘methods’ => ‘POST’,
‘callback’ => [$this, ‘restcreateitem’],
‘permissioncallback’ => [$this, ‘restpermissions_check’],
]);
}
public function restgetdata($request) {
$data = getoption(‘yourmodule_data’, []);
return new WPRESTResponse($data, 200);
}
public function restcreateitem($request) {
$params = $request->get_params();
// Validate and sanitize
$title = sanitizetextfield($params[‘title’]);
$content = wpksespost($params[‘content’]);
// Create post
$postid = wpinsert_post([
‘post_title’ => $title,
‘post_content’ => $content,
‘posttype’ => ‘youritem’,
‘post_status’ => ‘publish’,
]);
if (iswperror($post_id)) {
return new WPError(‘createfailed’, ‘Failed to create item’, [‘status’ => 500]);
}
return new WPRESTResponse([‘id’ => $post_id], 201);
}
public function restpermissionscheck($request) {
return currentusercan(‘edit_posts’);
}
`
Module Dependencies
Checking Dependencies
`php
public function check_dependencies() {
$dependencies = [
‘wordpress’ => ‘5.0’,
‘php’ => ‘7.4’,
‘modules’ => [‘core’, ‘settings’],
];
// Check WordPress version
if (versioncompare(getbloginfo(‘version’), $dependencies[‘wordpress’], ‘<')) {
return new WPError(‘dependencyerror’, ‘WordPress version too old’);
}
// Check PHP version
if (versioncompare(PHPVERSION, $dependencies[‘php’], ‘<')) {
return new WPError(‘dependencyerror’, ‘PHP version too old’);
}
// Check required modules
foreach ($dependencies[‘modules’] as $module) {
if (!ShahiAssist()->modules->is_active($module)) {
return new WPError(‘dependencyerror’, “Required module ‘{$module}’ not active”);
}
}
return true;
}
`
Optional Dependencies
`php
public function init() {
// Core functionality
// Optional features based on available modules
if (ShahiAssist()->modules->isactive(’emailnotifications’)) {
addaction(‘yourevent’, [$this, ‘send_notification’]);
}
if (ShahiAssist()->modules->is_active(‘webhooks’)) {
addaction(‘yourevent’, [$this, ‘send_webhook’]);
}
}
`
Testing and Debugging
Unit Tests
`php
class TestYourModule extends WP_UnitTestCase {
public function testmoduleinitialization() {
$module = new ShahiAssistYourModule();
$this->assertInstanceOf(‘ShahiAssistModuleBase’, $module);
}
public function testsettingsregistration() {
$module = new ShahiAssistYourModule();
$settings = $module->get_settings();
$this->assertArrayHasKey(‘enabled’, $settings);
}
public function testcustompost_type() {
$module = new ShahiAssistYourModule();
$module->init();
$this->assertTrue(posttypeexists(‘your_item’));
}
}
`
Integration Tests
`php
public function testfullworkflow() {
// Create test data
$post_id = $this->factory->post->create([
‘posttype’ => ‘youritem’,
‘post_title’ => ‘Test Item’,
]);
// Test API endpoint
$request = new WPRESTRequest(‘GET’, ‘/shahi-assist/v1/your-module’);
$response = restdorequest($request);
$this->assertEquals(200, $response->get_status());
}
`
Debug Logging
`php
public function debug_log($message, $data = null) {
if (defined(‘WPDEBUG’) && WPDEBUG) {
$log_message = ‘[Your Module] ‘ . $message;
if ($data) {
$logmessage .= ‘: ‘ . printr($data, true);
}
errorlog($logmessage);
}
}
`
Performance Optimization
Caching
`php
private function getcacheddata($key) {
$cachekey = ‘yourmodule_’ . $key;
$data = wpcacheget($cachekey, ‘shahiassist’);
if ($data === false) {
$data = $this->fetch_data($key);
wpcacheset($cachekey, $data, ‘shahiassist’, HOURINSECONDS);
}
return $data;
}
`
Lazy Loading
`php
public function enqueue_scripts() {
// Only load on specific pages
if (!$this->shouldloadscripts()) {
return;
}
wpenqueuescript(/ … /);
}
private function shouldloadscripts() {
global $post;
return issingular(‘youritem’) ||
(isa($post, ‘WPPost’) && hasshortcode($post->postcontent, ‘your_shortcode’));
}
`
Database Optimization
`php
public function createcustomtable() {
global $wpdb;
$tablename = $wpdb->prefix . ‘yourmodule_data’;
$charsetcollate = $wpdb->getcharset_collate();
$sql = “CREATE TABLE $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
data_key varchar(255) NOT NULL,
data_value longtext NOT NULL,
createdat datetime DEFAULT CURRENTTIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY datakey (datakey)
) $charset_collate;”;
require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’);
dbDelta($sql);
}
`
Security Best Practices
Input Validation
`php
public function validate_input($input) {
$sanitized = [];
$sanitized[‘title’] = sanitizetextfield($input[‘title’]);
$sanitized[’email’] = sanitize_email($input[’email’]);
$sanitized[‘url’] = escurlraw($input[‘url’]);
$sanitized[‘content’] = wpksespost($input[‘content’]);
return $sanitized;
}
`
Capability Checks
`php
public function admin_page() {
if (!currentusercan(‘manage_options’)) {
wpdie(_(‘You do not have sufficient permissions to access this page.’));
}
// Rest of the function
}
`
Nonce Verification
`php
public function process_form() {
if (!wpverifynonce($POST[‘yournonce’], ‘your_action’)) {
wp_die(‘Security check failed’);
}
// Process form
}
`
SQL Injection Prevention
`php
public function getdataby_id($id) {
global $wpdb;
return $wpdb->get_row(
$wpdb->prepare(
“SELECT * FROM {$wpdb->prefix}your_table WHERE id = %d”,
intval($id)
)
);
}
`
Distribution and Updates
Version Management
`php
protected $version = ‘1.0.0’;
public function get_version() {
return $this->version;
}
public function updateversion($newversion) {
$this->version = $new_version;
updateoption(‘yourmoduleversion’, $newversion);
// Run update routines if needed
$this->run_updates();
}
`
Update Routines
`php
private function run_updates() {
$currentversion = getoption(‘yourmoduleversion’, ‘1.0.0’);
if (versioncompare($currentversion, ‘1.1.0’, ‘<')) {
// Update to 1.1.0
$this->updateto110();
}
if (versioncompare($currentversion, ‘1.2.0’, ‘<')) {
// Update to 1.2.0
$this->updateto120();
}
}
private function updateto110() {
// Migration logic for 1.1.0
}
private function updateto120() {
// Migration logic for 1.2.0
}
`
Documentation and Support
README.md
`markdown
Your Module
A custom module for ShahiAssist that adds [functionality].
Features
Installation
Configuration
Settings are available in ShahiAssist → Settings → Your Module.
Usage
[Usage instructions]
API
[API documentation]
Changelog
1.0.0
`
Inline Documentation
`php
/**
* Process user input for your module
*
* @param array $input Raw input data
* @return array Sanitized input data
* @since 1.0.0
*/
public function process_input($input) {
// Implementation
}
`
Resources
Share this article
Still need help?
Our support team is ready to assist you with personalized guidance for your workspace.