{"id":31187,"date":"2014-09-20T16:47:07","date_gmt":"2014-09-20T16:47:07","guid":{"rendered":"https:\/\/wordpress.org\/plugins-wp\/rhj4-diagnostics\/"},"modified":"2014-10-09T15:32:56","modified_gmt":"2014-10-09T15:32:56","slug":"rhj4-diagnostics","status":"closed","type":"plugin","link":"https:\/\/wordpress.org\/plugins\/rhj4-diagnostics\/","author":13163505,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2","stable_tag":"trunk","tested":"3.9.40","requires":"3.0.1","requires_php":"","requires_plugins":"","header_name":"RHJ4 Diagnostics","header_author":"Bob Jones","header_description":"","assets_banners_color":"","last_updated":"2014-10-09 15:32:56","external_support_url":"","external_repository_url":"","donate_link":"http:\/\/bellinghamwordpressdevelopers.com\/donate","header_plugin_uri":"http:\/\/bellinghamwordpressdevelopers.com\/demonstrations\/","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":979,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":[],"upgrade_notice":{"1.0 = Initial version":""},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":0},"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":[],"tagged_versions":[],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":"1004569","resolution":"1","location":"assets"},"screenshot-2.png":{"filename":"screenshot-2.png","revision":"1004396","resolution":"2","location":"assets"},"screenshot-3.png":{"filename":"screenshot-3.png","revision":"1004396","resolution":"3","location":"assets"},"screenshot-4.png":{"filename":"screenshot-4.png","revision":"1004396","resolution":"4","location":"assets"},"screenshot-5.png":{"filename":"screenshot-5.png","revision":"1004396","resolution":"5","location":"assets"}},"screenshots":[],"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[2679,23519],"plugin_category":[59],"plugin_contributors":[129950],"plugin_business_model":[],"class_list":["post-31187","plugin","type-plugin","status-closed","hentry","plugin_tags-debugging","plugin_tags-diagnostics","plugin_category-utilities-and-tools","plugin_contributors-bob-jones","plugin_committers-rhj4"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/rhj4-diagnostics.svg","icon_2x":false,"generated":true},"screenshots":[{"src":"https:\/\/ps.w.org\/rhj4-diagnostics\/assets\/screenshot-1.png?rev=1004569","caption":""},{"src":"https:\/\/ps.w.org\/rhj4-diagnostics\/assets\/screenshot-2.png?rev=1004396","caption":""},{"src":"https:\/\/ps.w.org\/rhj4-diagnostics\/assets\/screenshot-3.png?rev=1004396","caption":""},{"src":"https:\/\/ps.w.org\/rhj4-diagnostics\/assets\/screenshot-4.png?rev=1004396","caption":""},{"src":"https:\/\/ps.w.org\/rhj4-diagnostics\/assets\/screenshot-5.png?rev=1004396","caption":""}],"raw_content":"<!--section=description-->\n<p>RHJ4 Diagnostics captures diagnostic messages written in PHP and conditionally directs them to various different logging functions. The plugin can be enabled or disabled during page execution, and it can intercept and handle various classes of PHP errors, e.g. E_ERROR &amp; ~E_NOTICE. The documentation includes numerous usage examples.<\/p>\n\n<p>Diagnostics works closely with RHJ4 Notifications. Each uses functionality in the other plugin.<\/p>\n\n<h3>Usage<\/h3>\n\n<h3>The Problem<\/h3>\n\n<p>Using trace statements is my preferred method of debugging when I am not \nexactly sure where the bug is coming from. A common method for implementing \ntracing is to use the PHP error_log function which writes a line of text \ninto a specific file that is identified in the PHP.ini configuration file.<\/p>\n\n<p>This method is simple and effective, but there are several problems that come\nalong with it:<\/p>\n\n<ol>\n<li>You have to go back through your code later and remove the error_log calls\nor they will slow the program down and fill the error log with what are now\nuseless messages.<\/li>\n<li>The log may also contain undesired \"noise\" in the form of PHP messages and\nstack dumps. Many of these you can control using the error_reporting (level)\nfunction, but some of these messages simply won't go away.<\/li>\n<li>Depending on your configuration, you may not have access to PHP.ini and you\nmay not be able to see the generated log because you don't have access \nrights to the location the log was written to.<\/li>\n<\/ol>\n\n<h3>RHJ4Diagnostics<\/h3>\n\n<p>Diagnostic problems can arise in the Javascript code executing in the browser\nor in PHP code executing in the server. In both cases, you want to be able to\neasily capture and report the condition.<\/p>\n\n<p>RHJ4Diagnostics reports its messages in several places: on the Browser's \ndebugging console, in the PHP error_log, or to a function you specify.<\/p>\n\n<p>Diagnostics can be turned on or off for an entire site or for a single section\nof code. Since the diagnostics are very lightweight, they don't have to be \nremoved from the code in order to be disabled.<\/p>\n\n<h3>PHP API<\/h3>\n\n<p>The PHP code is implemented as a class with the following functions:<\/p>\n\n<ul>\n<li><p>instance(): Return instance of plugin (does not initialize).<\/p><\/li>\n<li><p>init($options = NULL): Initialize plugin<\/p><\/li>\n<li><p>kill(): Kill current instance of plugin<\/p><\/li>\n<li><p>options ($options = null): parse and set options for currently loaded page<\/p><\/li>\n<li><p>set($options = NULL): parse and set options in wp&#095;options table. NOTE: Multisite is supported. Options will be set in wp&#095;$blog&#095;id&#095;options table.<\/p><\/li>\n<li><p>reset(): reset all options to their defaults<\/p><\/li>\n<li><p>diagnostic($message, $options = NULL): Capture a diagnostic message. NOTE: $if $options is a string, it will be treated as if it were: array('source' -&gt; 'whatever:').<\/p><\/li>\n<li><p>set&#095;error&#095;reporting($level = null): Set PHP error&#095;reporting&#095;level<\/p><\/li>\n<li><p>render&#095;error&#095;level($level): Translate integer error_level value to string<\/p><\/li>\n<\/ul>\n\n<h3>OPTIONS<\/h3>\n\n<p>The following options may be used for all functions that accept $options:<\/p>\n\n<ul>\n<li><em>enabled<\/em> enables plugin (default: false). If not enabled, no diagnostic messages will be displayed.<\/li>\n<li><em>threshold<\/em> sets a threshold that determines which messages will be logged. Messages with a threshold above the current threshold will not be written to the log file.<\/li>\n<li><em>output<\/em> identifies output handler function (default: 'rhj4_log'). Output may be a single function name or an array of function names. Function must exist to be set.<\/li>\n<li><em>source<\/em> identifies the body of code that diagnostics will be coming from. This string will be prepended to each message.<\/li>\n<li><em>logfile<\/em> identifies where output diagnostics will be saved (default: 'rhj4_diags.log').<\/li>\n<li><em>level<\/em> PHP error reporting level for PHP diagnostics (default: 71 = 64 + 4 + 2 + 1 = ERROR, WARNING, PARSE, COMPILE ERROR). PHP errors will be reported if WP_DEBUG is TRUE. RHJ4Diagnostics will be reported if plugin is enabled.<\/li>\n<\/ul>\n\n<p>Option values are stored in the wp_options table using the key 'rhj4_diagnostic_options'.<\/p>\n\n<h3>SHORTCODES<\/h3>\n\n<p>The shortcode format is:<\/p>\n\n<pre><code>    [rhj4_diagnostics &lt;code&gt;=&lt;value&gt; [...]]\n<\/code><\/pre>\n\n<p>The following code values are supported:<\/p>\n\n<p><strong>enable<\/strong> [true|false&lt;- default] Enables logging on this page.<\/p>\n\n<p><strong>disable<\/strong> [true|false&lt;- default] Disables logging on this page.<\/p>\n\n<p><strong>threshold<\/strong> [0 | integer value] Sets diagnostic threshold level. Only messages with this threshold or lower will be logged.<\/p>\n\n<p><strong>save<\/strong> [true|false&lt;- default] Used with Enable, Disable and Threshold to save settings\nto database. To enable diagnostics for all pages:<\/p>\n\n<pre><code>[rhj4_diagnostics enable=true save=true]\n<\/code><\/pre>\n\n<p><strong>show<\/strong> [true|false&lt;- default] Displays current log file contents.<\/p>\n\n<p><strong>clear<\/strong> [true|false&lt;- default] Deletes current log file.<\/p>\n\n<p><strong>options<\/strong> [true|false&lt;- default] Displays current option values on page.<\/p>\n\n<p><strong>demo<\/strong> [true|false&lt;- default] Shows a demonstration of many ways of using this plugin.<\/p>\n\n<p><strong>test<\/strong> [true|false&lt;- default] Performs some diagnostic tests on the code.<\/p>\n\n<p><strong>options<\/strong> [true|false&lt;- default] Shows the current option values.<\/p>\n\n<p><strong>verbose<\/strong> [true|false&lt;- default] Echos diagnostic information on the page.<\/p>\n\n<p><strong>log<\/strong> [true|false&lt;- default] Writes a diagnostic to the log. Requires message. For example:<\/p>\n\n<pre><code>    [rhj4_diagnostics log=true message='log this message']\n<\/code><\/pre>\n\n<p><strong>message<\/strong> =  is used with notify and log to define the message to be sent.<\/p>\n\n<p><strong>notify<\/strong> [true|false&lt;- default] Displays a notification popup using RHJ4Notifications. Requires message and uses sticky and type.<\/p>\n\n<pre><code>    [rhj4_diagnostics notify=true message='show this message in popup' sticky=true, type=NOTIFICATION_TYPE_WARNING]\n<\/code><\/pre>\n\n<p><strong>sticky<\/strong> [true|false&lt;- default] is used with notify to indicate whether the notification message is \"sticky\", i.e. will stay visible on the screen until a page turn or the message is deleted.<\/p>\n\n<p><strong>type<\/strong> =  (NOTIFICATION_TYPE_CONFIRMATION&lt;- default) indicates the type of notification to be generated.<\/p>\n\n<p>Example:<\/p>\n\n<pre><code>    [rhj4_diagnostics enable=true show=true clear=true show_options=true]\n<\/code><\/pre>\n\n<p>Will produce:<\/p>\n\n<h4>Options<\/h4>\n\n<pre><code>array (size=6)\n'enabled' =&gt; int 1\n'threshold' =&gt; int 10\n'output' =&gt; string 'rhj4_log' (length=8)\n'source' =&gt; string 'DIAG: ' (length=6)\n'logfile' =&gt; string 'rhj4_diags.log' (length=14)\n'level' =&gt; int 71\nLogfile: D:\\ApacheHtdocs\\bhamwpdev\/wp-content\/rhj4_diags.log\n\n09\/14\/14 04:56:09-&gt;DIAG: Page Name [] User [bob_jones]\n09\/14\/14 04:56:55-&gt;DIAG: Page Name [diags] User [bob_jones]\n\nrhj4_diags.log deleted\n<\/code><\/pre>\n\n<p>Example:<\/p>\n\n<pre><code>    [rhj4_diagnostics notify=true message=\"this is a notification\" verbose=true]\n<\/code><\/pre>\n\n<p>Will generate a popup window containing the notification message.<\/p>\n\n<p>NOTE: Use of the notify function requires the installation of the RHJ4 Notifications plugin.<\/p>\n\n<p>DEMONSTRATION Page: Visit <a href=\"http:\/\/bellinghamwordpressdevelopers.com\/diags\">http:\/\/bellinghamwordpressdevelopers.com\/diags<\/a> for a demonstration of these shortcodes in action.<\/p>\n\n<h3>EXAMPLES<\/h3>\n\n<p>There are two basic ways to invoke this plugin:<\/p>\n\n<ol>\n<li><p>Call rhj4_diagnostic and pass in the message and (optionally) any options<\/p><\/li>\n<li><p>Acquire an instance of the plugin and work with that:<\/p>\n\n<p>$diags = RHJ4Diagnostics::instance();<\/p>\n\n<p>$diags holds an instance of the diagnostics object and can be used to invoke methods in the object.<\/p><\/li>\n<\/ol>\n\n<p>These two lines are equivalent:<\/p>\n\n<pre><code>    $diags-&gt;diagnostic('message','SOURCE: ');\n    $diags-&gt;diagnostic('message', array('source' =&gt; 'SOURCE: '));\n<\/code><\/pre>\n\n<p>Enable plugin for this page and print a message:<\/p>\n\n<pre><code>    $diags-&gt;diagnostic('message', \n        array('source' =&gt; 'SOURCE: ', 'enabled' =&gt; true));\n<\/code><\/pre>\n\n<p>This code:<\/p>\n\n<pre><code>    rhj4_diagnostic('this is a message');\n<\/code><\/pre>\n\n<p>Will produce this output in the current log file:<\/p>\n\n<pre><code>08\/13\/14 23:36:44-&gt;DIAGNOSTICS:this is a message\n<\/code><\/pre>\n\n<p>This example:<\/p>\n\n<pre><code>    $diags = RHJ4Diagnostics::instance();\n    $diags = RHJ4Diagnostics::instance()-&gt;init(array (\n        'enabled'   =&gt; true,\n        'threshold' =&gt; 10,\n        'output'    =&gt; 'rhj4_log',\n        'source'    =&gt; 'DIAGNOSTICS:',\n        'logfile'   =&gt; 'rhj4_diags.log',\n        'level'     =&gt; E_ALL &amp; ~E_DEPRECATED &amp; ~E_NOTICE &amp; ~E_STRICT\n    ));\n\n    $diags-&gt;diagnostic($diags-&gt;plugin_slug.' enabled');\n<\/code><\/pre>\n\n<p>Will:<\/p>\n\n<ul>\n<li>Enable the plugin.<\/li>\n<li>Set the message threshold to 10.<\/li>\n<li>Set the output logging function ('rhj4_log).<\/li>\n<li>Identify the logging file ('rhj4_diags.log'). <\/li>\n<li>Tell the plugin to report all PHP errors except E&#095;DEPRECATED, E&#095;NOTICE and E&#095;STRICT.<\/li>\n<li><p>Write a line in the output file like this:<\/p>\n\n<p>08\/13\/14 23:36:42-&gt;DIAGNOSTICS:rhj4_diagnostics enabled<\/p><\/li>\n<\/ul>\n\n<h4>Demo Code<\/h4>\n\n<p>Add this line of code (or uncomment the line in the plugin source):<\/p>\n\n<pre><code>    add_action('init','rhj4_diagnostics_demo');\n<\/code><\/pre>\n\n<p>and the plugin will execute code in the function rhj4_diagnostics_demo:<\/p>\n\n<p>Get an instance of this plugin:<\/p>\n\n<pre><code>    $diags = RHJ4Diagnostics::instance();\n<\/code><\/pre>\n\n<p>Reset option settings to their defaults. The reset values are remembered in wp_options:<\/p>\n\n<pre><code>    $diags-&gt;clear_log();\n    $diags-&gt;reset();\n    $options = $diags-&gt;options();\n    var_dump($options);\n<\/code><\/pre>\n\n<p>After reset, plugin will not be enabled, so this next message won't show:<\/p>\n\n<pre><code>    $message = rhj4_diagnostic('This message will NOT appear in the log.');    \n    var_dump($message);\n<\/code><\/pre>\n\n<p>Enable plugin and change the source message:<\/p>\n\n<pre><code>    $message = $diags-&gt;diagnostic('This message WILL appear in log', array(\n       'enabled'    =&gt; true,\n   'source'     =&gt; 'DEMO: '\n    ));\n\n    $options = $diags-&gt;options();\n    var_dump($message);\n    var_dump($options);\n\n    $message = $diags-&gt;diagnostic('Turn on reporting of PHP Errors', array(\n        'level' =&gt; E_ALL ));\n\n    $options = $diags-&gt;options();\n    var_dump($message);\n    var_dump($options);\n\n    rhj4_diagnostic('End of demo','THE END: ');\n<\/code><\/pre>\n\n<h4>Custom Output Handlers<\/h4>\n\n<p>You can write your own output handlers that will direct diagnostics to any file (or database table) that you want. Here is an example:<\/p>\n\n<pre><code>    function my_diagnostic_test_output($message, $logfile = 'rhj4_diags_test.log') {\n        $timestamp = date('m\/d\/y H:i:s',time());\n        $file = fopen($logfile,\"a+\");\n        fwrite($file, $timestamp.'-&gt;'.$message.\"\\n\");\n        fclose($file);\n    }\n<\/code><\/pre>\n\n<h4>Multiple Output Handlers<\/h4>\n\n<pre><code>\/\/\n\/\/  This example writes the output to two log files \n\/\/\n    rhj4_diagnostic('more complex message', array(\n        'source' =&gt;'MULTIPLE FUNCTIONS: ',\n        'output' =&gt; array(\n            array(  'function' =&gt; 'my_diagnostic_test_output', \n                    'logfile' =&gt; 'rhj4_diags_test.log'),\n            array(  'function' =&gt; 'rhj4_log', \n                    'logfile' =&gt; 'rhj4_diags.log')\n        )));\n<\/code><\/pre>\n\n<h3>SUPPORT<\/h3>\n\n<p>I will attempt to answer your email as quickly as I can, but cannot promise immediate response.<\/p>\n\n<p>I will entertain ideas for enhancements, especially if I hear the same request from multiple people.<\/p>\n\n<p>Donations will encourage my support... and my thanks.<\/p>\n\n<h3>CONSULTING<\/h3>\n\n<p>I make my living by helping WordPress developers. If I can help you, please contact me.<\/p>\n\n<p>Bob Jones<\/p>\n\n<p><a href=\"mailto:&#098;&#111;&#098;&#064;&#114;&#104;&#106;&#052;&#046;&#099;&#111;&#109;\">bob@rhj4.com<\/a><\/p>\n\n<p><a href=\"http:\/\/bellinghamwordpressdevelopers.com\/\">http:\/\/bellinghamwordpressdevelopers.com\/<\/a><\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the contents of the zip file to the <code>\/wp-content\/plugins\/<\/code> directory<\/li>\n<li>Activate the plugin through the 'Plugins' menu in WordPress<\/li>\n<li>Enable plugin using shortcodes or explicitly in your code<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt>Why do I need this plugin?<\/dt>\n<dd><p>There are only three commonly used methods to debug code:<\/p>\n\n<ol>\n<li><p>Iteratively alter the code until you get the desired effect. \nThis is useful for fine-tuning screen layouts, but not for code bugs.<\/p><\/li>\n<li><p>Use diagnostic trace statements to capture critical flow information.<\/p><\/li>\n<li><p>Use a debugger with breakpoints so you can stop and examine code and\nvariables.<\/p><\/li>\n<\/ol>\n\n<p>This plugin makes it simple to write diagnostic information into files on the\nserver and onto the browser's console log. Diagnostics on the server can be\nwritten to multiple files simultaneously. PHP error diagnostics can be included\nor excluded, and diagnostics can be enabled at specific points in your code\nand disabled elsewhere.<\/p><\/dd>\n<dt>What makes this plugin better than simply invoking error_log?<\/dt>\n<dd><ol>\n<li>The error log file's location is defined in php.ini and, depending on your configuration, may not be visible to you.<\/li>\n<li>You can easily enable and disable logging at various places in your code. <\/li>\n<li>Diagnostic statements can be written into a variety of files or even databases.<\/li>\n<li>You can add the shortcode [rhj4_diagnostics show=true] to any page and see the entire contents of the current logfile.<\/li>\n<li>The shortcode [rhj4_diagnostics clear=true] will delete the logfile.<\/li>\n<\/ol><\/dd>\n<dt>Can I enable and disable logging without having to delete all my trace statements?<\/dt>\n<dd><p>RHJ4Diagnostics::instance('enabled'=&gt;true|false);<\/p><\/dd>\n<dt>Can I selectively enable or disable PHP error messages?<\/dt>\n<dd><p>$diags-&gt;option(array ('level' =&gt; E_ALL &amp; ~E_DEPRECATED &amp; ~E_NOTICE &amp; ~E_STRICT);<\/p><\/dd>\n<dt>Will it capture All PHP diagnostics except NOTICE and STRICT messages?<\/dt>\n<dd><p>$diags-&gt;option(array ('level' =&gt; 0);<\/p><\/dd>\n<dt>Will it disable capture of PHP diagnostics?<\/dt>\n<dd><\/dd>\n<dt>Can I label various messages so I can tell where they came from?<\/dt>\n<dd><p>$diags = RHJ4Diagnostics::instance();\n        $diags-&gt;diagnostic('Message # 1', 'FUNCTION A: ');\n        ...\n        $diags-&gt;diagnostic('Message # 2', 'FUNCTION B: ');\n        ...\n        $diags-&gt;diagnostic('Message # 3', 'FUNCTION C: ');<\/p><\/dd>\n<dt>Can I write some output into various different log files?<\/dt>\n<dd><p>$diags-&gt;diagnostic('Message text', array('output'=&gt; array(\n            'function' =&gt; 'my_diagnostic_test_output', 'logfile' =&gt; 'demo.log')));<\/p><\/dd>\n<dt>Can I selectively enable some diagnostic messages and disable others?<\/dt>\n<dd><p>Yes. The \"threshold\" option determines which messages will be displayed. \nIf the current threshold value is 10 and the message's threshold value is greater than 10, the message will not be logged. If the message threshold is 10 or less, it will be logged.<\/p>\n\n<pre><code>    $diags = RHJ4Diagnostics::instance();\n    $diags-&gt;options(array('enabled' =&gt; true, 'threshold' =&gt; 6);\n    $diags-&gt;diagnostic('This message will not be logged',array('threshold'=&gt;7));\n    $diags-&gt;diagnostic('This message will be logged',array('threshold'=&gt;5));\n<\/code><\/pre><\/dd>\n<dt>Can my settings be remembered across pages?<\/dt>\n<dd><p>Yes. On the first page establish your settings like this:<\/p>\n\n<pre><code>    $diags = RHJ4Diagnostics::instance();\n    $diags-&gt;set(array('enabled' =&gt; true, 'threshold' =&gt; 6);\n<\/code><\/pre><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2<\/h4>\n\n<p>Enhanced demo considerably.<\/p>\n\n<p>Added jQuery support for save, clear and show functions. It can now save a diagnostic generated in jQuery or PHP.<\/p>\n\n<p>Added rhj4_diagnostics_save, rhj4_diagnostics_show and rhj4_diagnostics_clear AJAX functions to support jQuery calls.<\/p>\n\n<h4>1.1<\/h4>\n\n<p>Added substantial shortcode support.\nAdded threshold option.<\/p>","raw_excerpt":"RHJ4 Diagnostics supports program debugging by making it simple to write tracing information into several log files.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/31187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=31187"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/rhj4"}],"wp:attachment":[{"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=31187"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=31187"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=31187"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=31187"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=31187"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=31187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}