• Home
  • Create Plugins
  • Contact Us
  • Demo
    Installation & MaintenancePersonalizationSettingsClient ManagementInvoices & PaymentsProjects & TasksTeam & CollaborationProductivity ToolsSales & ServicesPluginsFAQChange logs
  1. Docs
  2. Plugins

Available hooks for plugins

Call this hooks in your My_Plugin folder/index.php file.

Important: When you use add_filter hook function, always return the first parameter with/without modifying it as per needs.


  • Add a url to the CSRF exclude uris.
app_hooks()->add_filter('app_filter_app_csrf_exclude_uris', function ($app_csrf_exclude_uris) {
    if (!in_array("plugin_controller.*+", $app_csrf_exclude_uris)) {
        array_push($app_csrf_exclude_uris, "plugin_controller.*+");
    }

    return $app_csrf_exclude_uris;
});


  • Execute a script after running cron job.
app_hooks()->add_action('app_hook_after_cron_run', function() {
    //run something
});


  • Add a widget to custom dashboard panel.
app_hooks()->add_filter('app_filter_dashboard_widgets', function ($default_widgets_array) {
    array_push($default_widgets_array, array(
        "widget" => "widget_name",
        "widget_view" => view("My_Plugin\Views\widget")
    ));

    return $default_widgets_array;
});


  • Add some action links in Settings > Plugins table.
app_hooks()->add_filter('app_filter_action_links_of_My_Plugin', function ($action_links_array) {
    $action_links_array = array(
        anchor(get_uri("my_plugin/settings"), "Settings"),
        anchor(get_uri("my_plugin/get_support"), "Supports")
    );

    return $action_links_array;
});


  • User logged in successfully/there has logged in user who is about to access the app. This is the state of right before that.
app_hooks()->add_action('app_hook_before_app_access', function ($data) {
    $login_user_id = get_array_value($data, "login_user_id"); //logged in user id if it's valid login
    $redirect = get_array_value($data, "redirect"); //either it'll redirect to signin page or not if there has invalid login

    //perform something before accessing to the main app
});


  • Add a menu item for staff users.
app_hooks()->add_filter('app_filter_staff_left_menu', function ($sidebar_menu) {
    $sidebar_menu["left_menu_item"] = array(
        "name" => "item_name",
        "url" => "my_plugin/url",
        "class" => "feather-icon-class", //like book
        "position" => 5 //will be on the position after 4th item
    );

    return $sidebar_menu;
});


  • Add a menu item for client users.
app_hooks()->add_filter('app_filter_client_left_menu', function ($sidebar_menu) {
    $sidebar_menu["left_menu_item"] = array(
        "name" => "item_name",
        "url" => "my_plugin/url",
        "class" => "feather-icon-class", //like book
        "position" => 5 //will be on the position after 4th item
    );

    return $sidebar_menu;
});


  • A new notification created. Do something after that.
app_hooks()->add_action('app_hook_post_notification', function ($notification_id) {
    //do something
});


Create notifications. First, add the notification setting to notification_settings table while installing the plugin.

Note: On deactivation of your plugin, the notification setting will still be shown in notification settings. Because of this, use register_deactivation_hook() and set deleted=1 and register_activation_hook() to revert it again by deleted=0.

INSERT INTO `notification_settings` (`event`, `category`, `enable_email`, `enable_web`, `notify_to_team`, `notify_to_team_members`, `notify_to_terms`, `deleted`) VALUES
('your_notification_key', 'your_category', 0, 0, '', '', '', 0);


Also add the required id field as you needed to notifications table.

Note: Please add prefix (plugin_) with your field and note that, on deactivation of your plugin, the notifications will still be shown in user's notifications area. Because of this, use register_deactivation_hook() and set deleted=1 and register_activation_hook() to revert it again by deleted=0.


ALTER TABLE `notifications` ADD `plugin_your_item_id` INT(11) NOT NULL AFTER `deleted`;

  • Add notification settings category hook.
app_hooks()->add_filter('app_filter_notification_category_suggestion', function ($category_suggestions) {
    $category_suggestions[] = array("id" => "your_category", "text" => app_lang("your_category"));

    return $category_suggestions;
});


  • Add notification config hook.
app_hooks()->add_filter('app_filter_notification_config', function ($events_of_hook) {
    $notification_link = function () {
        return array("url" => get_uri("notification_link"));
    };

    $events_of_hook["your_notification_key"] = array( //check ...app/Helpers/notifications_helper.php > function get_notification_config() for better ideas
        "notify_to" => array("recipient"), //check available values below
        "info" => $notification_link
    );

    return $events_of_hook;
});


Supported notify_to array:

array("team_members", "team", "project_members", "client_primary_contact", "client_all_contacts", "task_assignee", "task_collaborators", "comment_creator", "cusomer_feedback_creator", "leave_applicant", "ticket_creator", "ticket_assignee", "estimate_request_assignee", "recipient", "mentioned_members", "owner", "client_assigned_contacts", "post_creator", "order_creator_contact");


Prepare query of getting notify_to users:

app_hooks()->add_filter('app_filter_create_notification_where_query', function ($where_queries_from_hook, $data) {
    //prepare WHERE query and return
    //check ...app/Models/Notifications_model.php > function create_notification() for better ideas

    /*
    The $data variable has this key values:
    "event" => Event key (your_notification_key).
    "user_id" => Which user created the notification. If it's 0, then it's created by the app.
    "options" => It contains another array of available notification item ids. Check ...app/Models/Notifications_model.php > function create_notification() for better ideas.
    "notify_to_terms" => Notify to terms array as selected in notification setting for this event. Like array("team_members", "team", "project_members").
    */

    $where_queries_from_hook[] = "YOUR QUERIES";
    return $where_queries_from_hook;
});


If you want to show more information with the notification, you'll have to add this hook:

//for web
app_hooks()->add_filter('app_filter_notification_description', function ($notification_descriptions, $notification) {
    $notification_descriptions[] = view("your_notification_description", array("notification" => $notification)), //check ...app/Views/notifications/notification_description.php
    return $notification_descriptions;
});


//for slack

app_hooks()->add_filter('app_filter_notification_description_for_slack', function ($notification_descriptions, $notification) {
    $notification_descriptions[] = view("your_notification_description_for_slack", array("notification" => $notification)) //check ...app/Views/notifications/notification_description_for_slack.php
    return $notification_descriptions;
});


  • Add email templates.
app_hooks()->add_filter('app_filter_email_templates', function ($templates_array) {
    $templates_array["account"]["your_email_template"] = array("USER_FIRST_NAME", "USER_LAST_NAME", "LOGO_URL", "SIGNATURE", "OR_ANY_VARIABLE_YOU_WANT_TO_ADD");

    return $templates_array;
});


This also requires to add this email template in email_templates table while installing the plugin.

INSERT INTO `email_templates` (`template_name`, `email_subject`, `default_message`, `custom_message`, `deleted`) VALUES ('your_email_template', 'Email subject', 'CONTENT OF YOUR EMAIL TEMPLATE', '', '0');


Customize email notification.

app_hooks()->add_filter('app_filter_send_email_notification', function ($data) {
    //available values in $data
    //check .../app/Helpers/notifications_helper.php > function send_notification_emails() for better ideas
    $notification_info = get_array_value($data, "notification");
    $parser_data = get_array_value($data, "parser_data");
    $user_language = get_array_value($data, "user_language");

    //check if it's your plugin's notification otherwise it'll send for all notifications
    if ($notification->event !== "your_notification_key") {
        return $data;
    }

    $Email_templates_model = model("App\Models\Email_templates_model");
    $email_template = $Email_templates_model->get_final_template("your_email_template", true);

    $parser_data["ANY_VARIABLE"] = "value";

    $parser = \Config\Services::parser();
    $message = get_array_value($email_template, "message_$user_language") ? get_array_value($email_template, "message_$user_language") : get_array_value($email_template, "message_default");
    $subject = get_array_value($email_template, "subject_$user_language") ? get_array_value($email_template, "subject_$user_language") : get_array_value($email_template, "subject_default");
    $message = $parser->setData($parser_data)->renderString($message); //modify email message
    $subject = $parser->setData($parser_data)->renderString($subject); //modify email subject

    //add attachment
    //showing demo of sending an invoice pdf
    $invoice_data = get_invoice_making_data(invoice_id);
    $attachement_url = prepare_invoice_pdf($invoice_data, "send_email");
    $email_options["attachments"] = array(array("file_path" => $attachement_url));

    $info_array = array(
        "subject" => $subject,
        "message" => $message,
        "email_options" => $email_options,
        "attachement_url" => $attachement_url,
    );

    return $info_array;
});


  • Add a payment method in the Settings > Setup > Payment methods table.
app_hooks()->add_filter('app_filter_payment_method_settings', function($settings) {
    $settings["payment_method_name"] = array(
        array("name" => "pay_button_text", "text" => app_lang("pay_button_text"), "type" => "text", "default" => "Payment Method"), //required
        array("name" => "payment_method_setting_text", "text" => "Payment method setting (Text)", "type" => "text", "default" => ""),
        array("name" => "payment_method_setting_boolean", "text" => "Payment method setting (Boolean)", "type" => "boolean", "default" => "0"),
        array("name" => "payment_method_setting_readonly", "text" => "Payment method setting (Readonly)", "type" => "readonly", "default" => "This is the readonly value"),
    );

    return $settings;
});


This also requires to add this payment method in payment_methods table while installing the plugin.

INSERT INTO `payment_methods` (`title`, `type`, `description`, `online_payable`, `available_on_invoice`, `minimum_payment_amount`, `settings`, `deleted`) VALUES ('Payment method name', 'payment_method_name', 'Payment method description', 1, 0, 0, '', 0);  


Note: On deactivation of a payment method plugin, the payment method will still be shown in payment method settings. Because of this, use register_deactivation_hook() and set deleted=1 and register_activation_hook() to revert it again by deleted=0.


Show activated payment methods in invoice view.

app_hooks()->add_action('app_hook_invoice_payment_extension', function($payment_method_variables) {
    if (get_array_value($payment_method_variables, "method_type") === "my_payment_method") {
        echo view("My_Payment_Method\Views\index", $payment_method_variables);
    }
});


The $payment_method_variables array() has this key values:

  1. method_type: The current payment method type of available activated payment methods.
  2. payment_method: The information array of payment method.
  3. balance_due: Total due balance for the invoice.
  4. currency: Currency for this invoice.
  5. invoice_info: The info object of invoice.
  6. invoice_id: Current invoice id.
  7. contact_user_id: For which client contact this invoice has been shared. (This variable will be available for public invoices)
  8. verification_code: The code to verify if it's a valid public invoice. (This variable will be available for public invoices)


  • Add ajax tab to several places.
//add ajax tab in staff profile 
app_hooks()->add_filter('app_filter_staff_profile_ajax_tab', function ($hook_tabs, $user_id) {
    $hook_tabs[] = array(
        "title" => app_lang("tab_title"),
        "url" => get_uri("my_plugin/my_tab"),
        "target" => "my-plugin-my-tab"
    );

    return $hook_tabs;
});


  • Available hooks to add ajax tabs:
app_hooks()->add_filter('app_filter_client_details_ajax_tab', 'function_to_add_tab'); //parameter: $hook_tabs, $client_id
app_hooks()->add_filter('app_filter_client_profile_ajax_tab', 'function_to_add_tab'); //parameter: $hook_tabs, $client_contact_id
app_hooks()->add_filter('app_filter_lead_details_ajax_tab', 'function_to_add_tab'); //parameter: $hook_tabs, $lead_id
app_hooks()->add_filter('app_filter_lead_profile_ajax_tab', 'function_to_add_tab'); //parameter: $hook_tabs, $lead_contact_id
app_hooks()->add_filter('app_filter_integration_settings_tab', 'function_to_add_tab'); //parameter: $hook_tabs


  • Add an item to settings.
app_hooks()->add_filter('app_filter_admin_settings_menu', function($settings_menu) {
    $settings_menu["setup"][] = array("name" => "my_plugin_setting", "url" => "my_plugin/setting");
    return $settings_menu;
});


  • Show something in the signin view.
app_hooks()->add_action('app_hook_signin_extension', function() {
    //show something
});


  • Show something in signup view.
app_hooks()->add_action('app_hook_signup_extension', function() {
    //show something
});


  • Show something in main view of page layout to a login user.
app_hooks()->add_action('app_hook_layout_main_view_extension', function() {
    //show something
});


  • Include something inside head tag.
app_hooks()->add_action('app_hook_head_extension', function() {
    //include something
});


  • Show something at the top of dashboard like announcement alerts.
app_hooks()->add_action('app_hook_dashboard_announcement_extension', function() {
    //show something
});


  • A user signed in.
app_hooks()->add_action('app_hook_after_signin', function() {
    //do something
});


  • A user signing out.
app_hooks()->add_action('app_hook_before_signout', function() {
    //do something
});


  • Add an option in role settings.
  • Show role within a <li></li> block. Check .../app/Views/roles/permissions.php file for better ideas. You'll get your permission value with array key like this: $your_permission = get_array_value($permissions, "your_permission");
app_hooks()->add_action('app_hook_role_permissions_extension', function () {
    //show a role setting
});          
  • Save role setting.
app_hooks()->add_filter('app_filter_role_permissions_save_data', function ($permissions) {
    $request = \Config\Services::request();
    $permissions["your_permission"] = $request->getPost('your_permission');

    return $permissions;
});


  • Show something on the right panel of task view.
app_hooks()->add_action('app_hook_task_view_right_panel_extension', function() {
    //show something
});


  • Add setting on several places.
  • Add option in general settings.
app_hooks()->add_action('app_hook_general_settings_extension', 'function_to_add_setting');
app_hooks()->add_action('app_hook_general_settings_save_data', 'function_to_save_setting');


  • Add option in client permissions setting.
app_hooks()->add_action('app_hook_client_permissions_extension', 'function_to_add_setting');
app_hooks()->add_action('app_hook_client_permissions_save_data', 'function_to_save_setting');


  • Add option in team member's my preferences setting.
app_hooks()->add_action('app_hook_team_members_my_preferences_extension', 'function_to_add_setting');
app_hooks()->add_action('app_hook_team_members_my_preferences_save_data', 'function_to_save_setting');


  • Add option in client's my preferences setting.
app_hooks()->add_action('app_hook_clients_my_preferences_extension', 'function_to_add_setting');
app_hooks()->add_action('app_hook_clients_my_preferences_save_data', 'function_to_save_setting');


Example:

Show option in general setting:

app_hooks()->add_action('app_hook_general_settings_extension', function() {
    //show settings
    //show a setting block (<div class="form-group">)
    //check .../app/Views/settings/general.php for better ideas
    echo view("My_Plugin\Views\setting");
});


Save setting:

app_hooks()->add_action('app_hook_general_settings_save_data', function () {
    $request = \Config\Services::request();
    $your_setting_value = $request->getPost("your_setting");

    $Settings_model = model("App\Models\Settings_model");
    $Settings_model->save_setting("your_setting", $your_setting_value);
});


  • Add ajax tab on project details page.
app_hooks()->add_filter('app_filter_team_members_project_details_tab', function ($project_tabs_of_hook_of_staff, $project_id = 0) {
    $project_tabs_of_hook_of_staff["my_tab_title_with_available_language_key_value"] = "my_plugin/my_tab_url";
    $project_tabs_of_hook_of_staff["my_tab_another_title_with_available_language_key_value"] = "my_plugin/my_another_tab_url";

    return $project_tabs_of_hook_of_staff;
});


//available filter for clients

app_hooks()->add_filter('app_filter_clients_project_details_tab', 'function_to_add_tab'); //parameter: $project_tabs_of_hook_of_staff, $project_id

              


  • Add custom storage integration.

1. First define the constant PLUGIN_CUSTOM_STORAGE on pre_system event.

Events::on('pre_system', function () {
    if (!defined('PLUGIN_CUSTOM_STORAGE')) {
        define('PLUGIN_CUSTOM_STORAGE', TRUE);
    }
});


2. While uploading a file, upload it to temporary directory first.

app_hooks()->add_action('app_hook_upload_file_to_temp', function ($data) {
    $temp_file = get_array_value($data, "temp_file");
    $file_name = get_array_value($data, "file_name");

    \Your_Storage_Integration\Libraries\Your_Storage_Integration::upload_file_to_temp($temp_file, $file_name);
    //check upload_file_to_temp() function on .../app/Helpers/app_files_helper.php for better ideas
});


3. Move temp file to permanent directory.

app_hooks()->add_filter('app_filter_move_temp_file', function ($data) {
    $related_to = get_array_value($data, "related_to");
    $file_name = get_array_value($data, "file_name");
    $new_filename = get_array_value($data, "new_filename");
    $file_content = get_array_value($data, "file_content");
    $source_path = get_array_value($data, "source_path");
    $target_path = get_array_value($data, "target_path");
    $direct_upload = get_array_value($data, "direct_upload");

    $files_data = \Your_Storage_Integration\Libraries\Your_Storage_Integration::move_temp_file($file_name, $new_filename); //use necessary parameters
    //check move_temp_file() function on .../app/Helpers/app_files_helper.php for better ideas

    return $files_data;
});


4. Download file by retrieving the content of file.

app_hooks()->add_filter('app_filter_get_file_content', function ($data) {
    $file_info = get_array_value($data, "file_info");

    $file_id = get_array_value($file_info, "file_id");
    //you can use any key here instead of file_id which is needed to download the content
    //but you should pass that key and value on app_filter_move_temp_file hook (on returning $files_data array)
    //check download_app_files() function on .../app/Controllers/App_Controller.php for better ideas

    return \Your_Storage_Integration\Libraries\Your_Storage_Integration::get_file_content($file_id); 
});


5. Get the source url of file to show preview.

app_hooks()->add_filter('app_filter_get_source_url_of_file', function ($data) {
    //check get_source_url_of_file() function on .../app/Helpers/app_files_helper.php for better ideas
    $file_info = get_array_value($data, "file_info");

    $file_id = get_array_value($file_info, "file_id");
    return \Your_Storage_Integration\Libraries\Your_Storage_Integration::get_source_url_of_file($file_id);
});


6. Delete file.

app_hooks()->add_action('app_hook_delete_app_file', function ($file_info) {
    //check delete_app_files() function on .../app/Helpers/app_files_helper.php for better ideas
    $file_id = get_array_value($file_info, "file_id");
    \Your_Storage_Integration\Libraries\Your_Storage_Integration::delete_file($file_id);
});


7. Process pasted images from content.

app_hooks()->add_filter('app_filter_process_images_from_content', function ($content) {
    //sometimes you may need to update the source url of pasted images in rich text editor
    return $updated_content;
}


  • Add a folder to Google Drive valid folders array. 
app_hooks()->add_filter('app_filter_add_folder_to_google_drive_valid_folders_array', function ($folders_array) {
    if (!in_array("your_folder", $folders_array)) {
        array_push($folders_array, "your_folder");
    }
    return $folders_array;
});
Was this article helpful? Yes No
How can we improve this article?
© 2026 Fairsketch
Home 3rd Party Plugins Get Support Buy Now

Delete?

Are you sure? You won't be able to undo this action!
To do