A Phoenix hook is a way of injecting your code into existing injection points in the Phoenix code base. Once a hook is in place, it can only be removed by removing the file or adjusting the code inside the hook file to disable it.
Consider the following simple php example:
<?php <!DOCTYPE html> <html> <head> <title>TEST PAGE</title> <?php echo $OSCOM_Hooks->call('siteWide', 'injectSiteStart'); ?> </head> <body> Test page - for a hooks example only. </body> </html>
If the above example was an existing area in the Phoenix core, it offers you the ability to write a hook into “injectSiteStart” which is between the html head tags.
Also notice that the hook is specific to “siteWide” which we will need to use to create our hook.
So let’s say that we wanted to do something simple, like add a remote css and js file to our store catalog. For this example, I will add https://select2.org/ which is a simple and searchable select box addon for long select lists. Select2 requires 2 files be added to the head of your website:
<link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" /> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
Since we know that we have a hook injector where we need it “injectSiteStart”, we can write a quick hook addon to Phoenix to get it those 2 files into the head of our site.
Create a new file, calling it something that is unique and wont collide with other addons. (Refer to rules)
We’ll call this file:
zipurSelect2.php
and we’ll place it in:
catalog/includes/hooks/shop/siteWide/
The above path refers to your “catalog” or base directory of your store.
Then the “shop” folder will hook the file to your front-end store. There is an “admin” directory as well, but we don’t want to show the select2 files in the admin for this example.
The “siteWide” folder is where any “siteWide” hooks will look for hooks to be. So in our example, this is exactly what we need.
Here is a simple zipurSelect2.php hook:
<?php /** * $Id: zipurSelect2.php * $Loc: catalog/includes/hooks/shop/siteWide/ * * zipurSelect2 * Version: 0.1.0 * Author: Preston Lord * aka zipurman / zipur.ca / plord@inetx.ca * * Revision Date: 08/05/2020 * Created to add https://select2.org to Phoenix * * Copyright (c) 2020: Preston Lord - @zipurman * All rights reserved. * Released under the GNU General Public License */ class hook_shop_siteWide_zipurSelect2 { function listen_injectSiteStart() { return <<<files <link href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" rel="stylesheet" /> <script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script> files; } }
The above example shows the following:
- A comment block should always be added to the top of your file to show the details, author, copyright, etc.
- The class name hook_shop_siteWide_zipurSelect2 is very important.
This should match the path of the file.
Consider:- filename: catalog/includes/hooks/shop/siteWide/zipurSelect2.php
- class name: hook_shop_siteWide_zipurSelect2
- note: the class has a singular “hook” where the path has a plural “hooks“
- You can add multiple methods(functions) to your class, but for this simple example we only need one
- listen_injectSiteStart()
- This method is what glues this hook to the $OSCOM_Hooks->call(‘siteWide’, ‘injectSiteStart’) that is in the core. The core will look for all classes containing a listen_injectSiteStart() that are in the siteWide folder, or any other area folder (we’ll cover that later).
- Now inside the method/function, you could inject anything you need. In this case we have a css file and a js file and that is all. We simply create a heredoc(files) that returns those 2 files as the hook result. If you are not familiar with php heredoc/nowdoc, I would suggest you read.
Once the above is saved in the path described in the example, you should see the 2 files included in your html of your store.
There are many more complicated things you can do with hooks … I’ll get some of those added to the docs as I continue to write them.