{"id":20023985,"url":"https://github.com/thebojda/jin-plugin","last_synced_at":"2026-05-12T17:51:19.786Z","repository":{"id":31747132,"uuid":"35313212","full_name":"TheBojda/jin-plugin","owner":"TheBojda","description":"Automatically exported from code.google.com/p/jin-plugin","archived":false,"fork":false,"pushed_at":"2015-05-10T20:52:11.000Z","size":384,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-12T16:43:05.874Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheBojda.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-05-09T03:22:14.000Z","updated_at":"2020-04-18T05:53:19.000Z","dependencies_parsed_at":"2022-08-29T16:00:53.647Z","dependency_job_id":null,"html_url":"https://github.com/TheBojda/jin-plugin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheBojda%2Fjin-plugin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheBojda%2Fjin-plugin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheBojda%2Fjin-plugin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheBojda%2Fjin-plugin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheBojda","download_url":"https://codeload.github.com/TheBojda/jin-plugin/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241455592,"owners_count":19965637,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T08:48:51.594Z","updated_at":"2026-05-12T17:51:19.757Z","avatar_url":"https://github.com/TheBojda.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"jin-plugin is a simple plugin framework for Java and PHP.\n\nThere are some existing plugin framework for Java (OSGI, jpf, etc.) and PHP, but all of them was too complex for my needs. jin-plugin is a minimalistic solution.\n\nLook at a Java example, which loads the plugins from the 'plugins' directory:\n\n```java\nPluginManager pm = PluginManagerFactory.createPluginManager(\"plugins\");\npm.init();\n```\n\nand the same in PHP:\n\n```php\n$pm = PluginManagerFactory::createPluginManager('plugins');\n$pm-\u003einit();\n```\n\nBoth of the codes load plugins from the plugins directory. Every plugin is a directory in the plugins folder. All of them contains a plugin.yaml file which describes the plugin dependencies and the plugin class.\n\nExample plugin.yaml in Java:\n\n```yaml\nplugin_class: com.estontorise.plugin.test.Plugin1\ndependencies: plugin2\n```\n\nand PHP:\n\n```yaml\nplugin_class: plugin1\ndependencies: plugin2\n```\n\nThe plugin directory contains the plugin classes. If you use PHP, the classes are directly in the plugin directory, if you use Java, classes must be in the classes directory, and  libraries in the lib directory.\n\nThe plugin class is very simple. It implements the Plugin interface, which has a simple init method. Plugins can register services, which can be used by other plugins.\n\nAn example in Java:\n\n```java\npublic class Plugin2 implements Plugin {\n\n    @Override\n    public void init(PluginManager pm) {\n        System.out.println(\"plugin2 initialized!\");\n        pm.registerService(\"testService\", new TestService());\n    }\n\n}\n\npublic class Plugin1 implements Plugin {\n\n\t@Override\n\tpublic void init(PluginManager pm) {\n\t\tSystem.out.println(\"plugin1 initialized!\");\n\t\tTestService testService = (TestService) pm.getService(\"testService\");\n\t\ttestService.testFunction();\n\t}\n\n}\n```\n\nand the same in PHP:\n\n```php\nclass plugin2 implements Plugin {\n\t\n\tpublic function init($pluginManager) {\n\t\techo \"plugin2 initialized!\u003cbr/\u003e\";\n\t\t$pluginManager-\u003eregisterService(\"testService\", new TestService);\n\t}\n\t\t\n}\n\nclass plugin1 implements Plugin {\n\t\n\tpublic function init($pluginManager) {\n\t\techo \"plugin1 initialized!\u003cbr/\u003e\";\n\t\t$testService = $pluginManager-\u003egetService(\"testService\");\n\t\t$testService-\u003etestFunction();\n\t}\n\t\n}\n```\n\n# Action support\n\nActions are hooks (or callbacks) which can be called on different places in the plugin or service. Every action is a list of action processor, and every service can add its own processors to the specified action. For example: you have a blog plugin which renders the list of blog entires. If you call an action if an entry is entered, you make possible for 3rd parties to add something to the end of the entries. It can be a \"share this\" line, or a Facebook Like button, etc. \n\nLook at a simple example in Java for the action support. The first code sample defines the test_action which do something, call another action (test_hook), and after that do something other. \n\n```java\npublic void init(final PluginManager pm) {\n\tpm.addActionProcessor(\"test_action\", new ActionProcessor() {\n\t\t\t\n\t\t@Override\n\t\tpublic void call(Map\u003cString, Object\u003e context) {\n\t\t\tSystem.out.println(\"Before test_hook ...\");\n\t\t\tpm.callAction(\"test_hook\", context);\n\t\t\tSystem.out.println(\"After test_hook ...\");\t\t\t\t\n\t\t}\n\t\t\t\n\t});\n}\n```\n\nand the same in PHP:\n\n```php\nclass TestAction implements ActionProcessor {\n\n\tpublic function __construct($pluginManager) {\n\t\t$this-\u003epluginManager = $pluginManager;\n\t}\n\n\tpublic function call(\u0026$context) {\n\t\techo \"Before test_hook ...\u003cbr/\u003e\";\n\t\t$this-\u003epluginManager-\u003ecallAction(\"test_hook\", $context);\n\t\techo \"After test_hook ...\u003cbr/\u003e\";\n\t}\n\t\n}\n\nclass plugin2 implements Plugin {\n\t\t\n\tpublic function init($pluginManager) {\n\t\t$pluginManager-\u003eaddActionProcessor(\"test_action\", new TestAction($pluginManager));\n\t}\n\t\t\n}\n```\n\nThe second code registers an action processor to the test_hook, and calls the test_action.\n\n```java\npublic void init(PluginManager pm) {\n\tpm.addActionProcessor(\"test_hook\", new ActionProcessor() {\n\t\t\t\n\t\t@Override\n\t\tpublic void call(Map\u003cString, Object\u003e context) {\n\t\t\tSystem.out.println(\"Test hook called!\");\n\t\t}\n\t\t\t\n\t});\n\tpm.callAction(\"test_action\", new HashMap\u003cString, Object\u003e());\n}\n```\n\nand the same in PHP:\n\n```php\nclass TestHookProcessor implements ActionProcessor {\n\t\t\t\n\tpublic function call(\u0026$context) {\n\t\techo \"Test hook called!\u003cbr/\u003e\";\n\t}\n\t\t\t\n}\n\t\nclass plugin1 implements Plugin {\n\t\t\n\tpublic function init($pluginManager) {\n\t\t$pluginManager-\u003eaddActionProcessor(\"test_hook\", new TestHookProcessor);\n\t\t$context = array();\n\t\t$pluginManager-\u003ecallAction(\"test_action\", $context);\n\t}\n\t\t\n}\n```\n\n# Update support\n\njin-plugin has an easy update mechanism. The plugin yaml can contain an update url and a version number. Look at a simple example:\n\n```yaml\nplugin_class: plugin3\ndependencies: plugin2\nupdate_url: http://localhost/jin-plugin-php/update_test.php\nversion: 1.0\n``` \n\nThe update_url points to the update site. The update site can be called with or without version parameter. Both of the cases the update site gives a list of urls in json format. If the version parameter is not set, the update site gives back the url of the actual release, if it is set, the script gives beck the urls of the updates to upgrade the plugin to the actual version. Every URL points to a zip file. You can use the update functionality through 3 method. \n\nThe first is ```installPlugin```. The parameter of the method is the url of an update site. This method calls the update site URL without any parameter, downloads the zip file from the given url, unpacks it to the plugin directory, and deletes zip file.\n\nUsage: ```$pm-\u003einstallPlugin('http://localhost/jin-plugin-php/update_test.php');```\n\nThe ```checkPluginUpdates``` method checks the update site of the plugins, and gives back an associative list, where an url list is assigned to every plugin.\n\nThe third method is ```updatePlugin```, which downloads and installs the updates for the plugin which name are given in the parameter list. \n\nUsage: ```$pm-\u003eupdatePlugin('plugin3');```\n\nSee also:\n\n[jin-template](https://github.com/TheBojda/jin-template/) - simple template engine for Java and PHP, using plain HTML as source\n\n[jin-webcore](https://github.com/TheBojda/jin-webcore/) - minimalistic web framework for Java and PHP\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthebojda%2Fjin-plugin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthebojda%2Fjin-plugin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthebojda%2Fjin-plugin/lists"}