]> jfr.im git - irc/unrealircd/unrealircd-webpanel.git/commitdiff
Add hooking system and example plugin
authorValerie Pond <redacted>
Mon, 9 Jan 2023 00:15:00 +0000 (00:15 +0000)
committerValerie Pond <redacted>
Mon, 9 Jan 2023 00:15:00 +0000 (00:15 +0000)
Add a way for developers to be able to extend the navigation bar and provide their own pages

An example plugin can be found at `plugins/example_plugin/`

channels.php [new file with mode: 0644]
common.php
config.php.sample
header.php
hook.php [new file with mode: 0644]
plugins.php [new file with mode: 0644]
plugins/example_plugin/example.php [new file with mode: 0644]
plugins/example_plugin/example_plugin.php [new file with mode: 0644]

diff --git a/channels.php b/channels.php
new file mode 100644 (file)
index 0000000..dcee7c6
--- /dev/null
@@ -0,0 +1,40 @@
+<?php
+require_once "common.php";
+
+require_once "header.php";
+
+if (!empty($_POST))
+{
+    do_log($_POST);
+
+    /* Nothing being posted yet */
+
+}
+
+$channels = $rpc->channel()->getAll();
+
+?>
+
+<table class='users_overview'>
+       <th>Name</th>
+       <th>Created</th>
+       <th>User count</th>
+       <th>Topic</th>
+       <th>Topic Set</th>
+       <th>Modes</th>
+       
+       <?php
+               foreach($channels as $channel)
+               {
+                       echo "<tr>";
+                       echo "<td>".$channel->name."</td>";
+                       echo "<td>".$channel->creation_time."</td>";
+                       echo "<td>".$channel->num_users."</td>";
+                       $topic = (isset($channel->topic)) ? $channel->topic : "";
+                       echo "<td>".$topic."</td>";
+                       $setby = (isset($channel->topic)) ? "By ".$channel->topic_set_by .", at ".$channel->topic_set_at : "";
+                       echo "<td>".$setby."</td>";
+                       $modes = (isset($channel->modes)) ? "+" . $channel->modes : "<none>";
+                       echo "<td>".$modes."</td>";
+               }
+       ?></table>
\ No newline at end of file
index 3950d60ce5e56bdbad6386ca876a6323f78c6473..af0cfa7ff236c210507a924f1b1bdefdbcd67671 100644 (file)
@@ -1,6 +1,8 @@
 <?php
 define('UPATH', dirname(__FILE__));
 require_once "config.php";
+require_once "hook.php";
+require_once "plugins.php";
 require_once UPATH . '/vendor/autoload.php';
 require_once "connection.php";
 require_once "Classes/class-log.php";
@@ -13,3 +15,27 @@ $pages = Array("Overview"    => "overview.php",
                "Server Bans"   => "tkl.php",
                "Spamfilter"    => "spamfilter.php",
                "News"          => "news.php");
+
+
+Hook::run(HOOKTYPE_NAVBAR, $pages);
+
+/* Example to add new menu item:
+ * 
+ * Example to add a navigation bar:
+ * 
+ * class MyPlugin
+ * {
+ * 
+ *      function __construct()
+ *      {
+ *          Hook::func(HOOKTYPE_NAVBAR, [$this, 'add_menu'])
+ *      }
+ * 
+ *      function add_menu(&$pages) // this should pass by reference (using the & prefix)
+ *      {
+ *          $page_name = "My New Page";
+ *          $page_link = "link/to/page.php";
+ *          $pages[$page_name] = $page_link;
+ *      }
+ * }
+*/
\ No newline at end of file
index c40af52c2ac1a25ce6ab93f4eadfe472b4b446be..54432b1402b465961aa739ad152e3ef462f7118c 100644 (file)
@@ -38,4 +38,18 @@ define( 'UNREALIRCD_SSL_VERIFY', false );
 /**
  * You should only need this if you're developing something.
 */
-define( 'UNREALIRCD_DEBUG', false );
\ No newline at end of file
+define( 'UNREALIRCD_DEBUG', false );
+
+
+/**
+ * Your list of plugins:
+ */
+define(
+    'PLUGINS', [
+
+        /*  This is where you should type the name(s) of your plugins. 
+         *  Uncomment the following line to view the live example
+        */
+        //"example_plugin",
+    ]
+);
\ No newline at end of file
index 10a951886695359f3b8f4fff40c63c758f0f78c7..cb6f6e1d9a31442f20821e7755cd1512aedde173 100644 (file)
@@ -7,6 +7,7 @@
 <h2><a href="">UnrealIRCd <small>Administration Panel</small></a></h2></div>
 <script src="js/unrealircd-admin.js" defer></script>
 <div class="topnav">
+    
 <?php
 foreach($pages as $name=>$page)
 {
@@ -17,6 +18,6 @@ foreach($pages as $name=>$page)
     }
     echo "<a ".$active."href=\"$page\">$name</a>\n";
 }
-//phpinfo();
+
 ?>
 </div>
diff --git a/hook.php b/hook.php
new file mode 100644 (file)
index 0000000..5025454
--- /dev/null
+++ b/hook.php
@@ -0,0 +1,70 @@
+<?php
+
+define('HOOKTYPE_NAVBAR', 100); /* The Hook for the navigation bar */
+
+/** 
+ *  Class for "Hook"
+ * This is the main function which gets called whenever you want to use a Hook.
+ * 
+ * Example:
+ * Calling the Hook using a function:
+ * Hook::func(HOOKTYPE_NAVBAR, 'bob');
+ * 
+ * This Hook references the function 'bob', and will run this
+ * function bob
+ * {
+ *     echo "We rehashed!";
+ * }
+ * 
+ * Example 2:
+ * Calling the Hook using an initialized object class method:
+ * Hook::func(HOOKTYPE_NAVBAR, [$this, 'method']);
+ * 
+ * Example 3:
+ * Calling the Hook using a static class method:
+ * Hook::func(HOOKTYPE_NAVBAR, ['class_name', 'method']);
+ * 
+ */
+class Hook {
+
+       /** A static list of Hooks and their associated functions */
+       private static $actions = [];
+
+       /** Runs a Hook.
+        * The parameter for $Hook should be a "HOOKTYPE_" as defined in hook.php
+        * @param string $Hook The define or string name of the Hook. For example, HOOKTYPE_REHASH.
+        * @param array &$args The array of information you are sending along in the Hook, so that other functions may see and modify things.
+        * @return void Does not return anything.
+        * 
+        */
+       public static function run($Hook, &$args = array())
+       {
+        if (!empty(self::$actions[$Hook]))
+            foreach (self::$actions[$Hook] as &$f)
+                $f($args);
+            
+       }
+
+       /** Calls a Hook
+        * @param string $Hook The define or string name of the Hook. For example, HOOKTYPE_REHASH.
+        * @param string|Closure $function This is a string reference to a Closure function or a class method.
+        * @return void Does not return anything.
+        */
+       public static function func($Hook, $function)
+    {
+               self::$actions[$Hook][] = $function;
+       }
+
+       /** Deletes a Hook
+        * @param string $Hook The Hook from which we are removing a function reference.
+        * @param string $function The name of the function that we are removing.
+        * @return void Does not reuturn anything.
+        */
+
+       public static function del($Hook, $function)
+    {
+               for ($i = 0; isset(self::$actions[$Hook][$i]); $i++)
+                   if (self::$actions[$Hook][$i] == $function)
+                       array_splice(self::$actions[$Hook],$i);
+       }
+}
diff --git a/plugins.php b/plugins.php
new file mode 100644 (file)
index 0000000..39ee1d5
--- /dev/null
@@ -0,0 +1,104 @@
+<?php
+
+require_once "config.php";
+
+require_once "common.php";
+
+require_once "Classes/class-message.php";
+
+
+/** Check for plugins and load them.
+ * 
+ * This expects your plugin folder to be located in `plugins/` and that the directory name,
+ * constructor file name and class name are identical.
+ * For example:
+ * You must have a file structure like this: plugins/myplugin/myplugin.php
+ * Which contains a class like this:
+ * ```
+ * class myplugin {
+ *      $name = "My plugin";
+ *      $author = "Joe Bloggs";
+ *      $version "1.0";
+ *      $desc = "This is my plugin and it does stuff";
+ *      
+ *      // rest of code here...
+ * }
+ * ```
+ * Your plugin class must be constructable and contain the following public variables:
+ * $name    The name or title of your plugin.
+ * $author  The name of the author
+ * $version The version of the plugin
+ * $description    A short description of the plugin
+*/
+class Plugins
+{
+    static $list = [];
+
+    static function load($modname)
+    {
+        $plugin = new Plugin($modname);
+        if ($plugin->error)
+        {
+            Message::Fail("Warning: Plugin \"$modname\" failed to load: $plugin->error");
+        }
+        else
+        {
+            self::$list[] = $plugin;
+        }
+    }
+}
+
+class Plugin
+{
+    public $name;
+    public $author;
+    public $version;
+    public $description;
+    public $handle;
+
+    public $error = NULL;
+    function __construct($handle)
+    {
+        if (!is_dir("plugins/$handle"))
+            $this->error = "Plugin directory \"plugins/$handle\" doesn't exist";
+
+        else if (!is_file("plugins/$handle/$handle.php"))
+            $this->error = "Plugin file \"plugins/$handle/$handle.php\" doesn't exist";
+
+        else
+        {
+            require_once "plugins/$handle/$handle.php";
+
+            if (!class_exists($handle))
+                $this->error = "Class \"$handle\" doesn't exist";
+
+            else
+            {
+                $plugin = new $handle();
+            
+                if (!isset($plugin->name))
+                    $this->error = "Plugin name not defined";
+                elseif (!isset($plugin->author))
+                    $this->error = "Plugin author not defined";
+                elseif (!isset($plugin->version))
+                    $this->error = "Plugin version not defined";
+                elseif (!isset($plugin->description))
+                    $this->error = "Plugin description not defined";
+                else
+                {
+                    $this->handle = $handle;
+                    $this->name = $plugin->name;
+                    $this->author = $plugin->author;
+                    $this->version = $plugin->version;
+                    $this->description = $plugin->description;
+                }
+            }
+        }
+    }
+}
+
+if (defined('PLUGINS'))
+{
+    foreach(PLUGINS as $plugin)
+        Plugins::load($plugin);
+}
\ No newline at end of file
diff --git a/plugins/example_plugin/example.php b/plugins/example_plugin/example.php
new file mode 100644 (file)
index 0000000..e5281d8
--- /dev/null
@@ -0,0 +1,3 @@
+<?php
+require_once "../../header.php";
+echo "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";
\ No newline at end of file
diff --git a/plugins/example_plugin/example_plugin.php b/plugins/example_plugin/example_plugin.php
new file mode 100644 (file)
index 0000000..b21009e
--- /dev/null
@@ -0,0 +1,21 @@
+<?php
+
+class example_plugin
+{
+    public $name = "Example plugin";
+    public $author = "Valware";
+    public $version = "1.0";
+    public $description = "An example plugin to show how to make stuff";
+
+    function __construct()
+    {
+        Hook::func(HOOKTYPE_NAVBAR, 'example_plugin::add_navbar'); 
+    }
+
+    public static function add_navbar(&$pages)
+    {
+        $page_name = "Example";
+        $page_link = "plugins/example_plugin/example.php";
+        $pages[$page_name] = $page_link;
+    }
+}
\ No newline at end of file