{"id":960,"date":"2021-04-20T16:56:35","date_gmt":"2021-04-20T14:56:35","guid":{"rendered":"https:\/\/wiki.ad-libitum.info\/?page_id=960"},"modified":"2021-04-23T16:06:14","modified_gmt":"2021-04-23T14:06:14","slug":"hooks-finden","status":"publish","type":"page","link":"https:\/\/wiki.ad-libitum.info\/?page_id=960","title":{"rendered":"Hooks finden"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Achtung: Das Folgende funktioniert auf dem XAMPP nicht, weil da zwar die Abfrage <code>is_writable<\/code> true ergibt, das <code>file_put_contents<\/code> aber wegen Permission denied fehlschl\u00e4gt. Der Pfad f\u00fcr XAMPP muss \u00fcbrigens so eingegeben werden: <code>\\\\xampp\\\\htdocs\\\\hausnertest\\\\hooks.log<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When I am developing a theme or plugin for WordPress, I often have to deal with the so called <a href=\"http:\/\/codex.wordpress.org\/Plugin_API\/Hooks\" target=\"_blank\" rel=\"noreferrer noopener\">hooks<\/a>, more precisely \u201cactions\u201d and \u201cfilters\u201d. There are a ton of those hooks in the WordPress core, giving the developer the ability to add custom functionality or output.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The difficult part with WordPress hooks, at least for me, is to find out the right action or filter for the job I am working on. I can use&nbsp;the official WordPress documentation pages for <a href=\"http:\/\/codex.wordpress.org\/Plugin_API\/Filter_Reference\" target=\"_blank\" rel=\"noreferrer noopener\">filters<\/a> and <a href=\"http:\/\/codex.wordpress.org\/Plugin_API\/Action_Reference\" target=\"_blank\" rel=\"noreferrer noopener\">actions<\/a>&nbsp;in the hope of finding a well documented hook&nbsp;which might be the right one for me. But if it is not one of the commonly used hooks (like \u201cinit\u201d or \u201cadmin_init\u201d), I often do not know if the hook will even apply on the page or function I am about to customize.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It even gets more difficult if I try to customize a third party plugin. If it uses hooks at all, you are very lucky if they are documented in a way you can work with.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So the best option for me is to not rely on the&nbsp;more or less&nbsp;good hook documentation, but to find out for myself&nbsp;<strong>which hooks apply on a page when the user accesses it<\/strong>. To achieve this I use a combination of Apache environment variables and two small core hacks in my WordPress development installation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 1: .htaccess<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In the <strong>.htaccess<\/strong> file I add these environment variables:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">(Make sure that no invisible control characters are created from copying and pasting!)<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">SetEnv    LOG_ACTIONS &nbsp; &nbsp; &nbsp; 0\nSetEnv    LOG_ACTIONS_NEEDLE\nSetEnv&nbsp;&nbsp;&nbsp;&nbsp;LOG_FILTERS &nbsp; &nbsp; &nbsp; 0\nSetEnv    LOG_FILTERS_NEEDLE\nSetEnv&nbsp;&nbsp;&nbsp;&nbsp;LOG_HOOKS_PATH &nbsp; &nbsp;[local_path_to_wp]\/wp-content\/hooks.log<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see, I create a new writeable file, \u201c<strong>hooks.log<\/strong>\u201c, in wp-content, which will be used as a hooks log file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you only want to display certain filters or actions, use the \u201cNEEDLE\u201d values to narrow them down (write a string after the respective NEEDLE variable).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Step 2: Core hacks<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Then I add two hacks in <strong>wp-includes\/plugin.php<\/strong>. (Note: This is just for development. Don\u2019t do this on your production site.)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In the function <strong>apply_filters<\/strong> I add (the part after the globals):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">function apply_filters( $tag, $value ) {\n    global $wp_filter, $merged_filters, $wp_current_filter;\n    \n    if (getenv('LOG_FILTERS') == '1' &amp;&amp; is_writable(getenv('LOG_HOOKS_PATH'))) {\n        $needle = getenv('LOG_FILTERS_NEEDLE');\n        if (empty($needle) || (!empty($needle) &amp;&amp; strpos($tag, $needle) !== false)) {\n            $data = __FUNCTION__ . ': ' . $tag . \"\\n\";\n\t\tfile_put_contents(getenv('LOG_HOOKS_PATH'), $data, FILE_APPEND);\n\t    }\n    }\n\n    ...<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">and in <strong>do_action<\/strong> I add&nbsp;(the part after the globals):<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">function do_action($tag, $arg = '') {\n    global $wp_filter, $wp_actions, $merged_filters, $wp_current_filter;\n\n    if (getenv('LOG_ACTIONS') == '1' &amp;&amp; is_writable(getenv('LOG_HOOKS_PATH'))) {\n        $needle = getenv('LOG_ACTIONS_NEEDLE');\n        if (empty($needle) || (!empty($needle) &amp;&amp; strpos($tag, $needle) !== false)) {\n            $data = __FUNCTION__ . ': ' . $tag . \"\\n\";\n&nbsp;&nbsp;&nbsp;&nbsp;        file_put_contents(getenv('LOG_HOOKS_PATH'), $data, FILE_APPEND);\n        }\n    }\n \n    ...<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Usage<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Now, whenever I need information about the&nbsp;applied hooks on a page I am working on, I can switch&nbsp;LOG_ACTIONS and \/ or&nbsp;LOG_FILTERS to 1 in the .htaccess file of my test system, reload the page and check the contents of wp-content\/hooks.log which may look like in the example screenshot generated on the login page:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.ifeelweb.de\/wp-content\/uploads\/2015\/01\/wp_hooks_log.jpg\" alt=\"https:\/\/www.ifeelweb.de\/wp-content\/uploads\/2015\/01\/wp_hooks_log.jpg\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Achtung: Das Folgende funktioniert auf dem XAMPP nicht, weil da zwar die Abfrage is_writable true ergibt, das file_put_contents aber wegen Permission denied fehlschl\u00e4gt. Der Pfad f\u00fcr XAMPP muss \u00fcbrigens so eingegeben werden: \\\\xampp\\\\htdocs\\\\hausnertest\\\\hooks.log. When I am developing a theme or plugin for WordPress, I often have to deal with the so called hooks, more precisely [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-960","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=\/wp\/v2\/pages\/960","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=960"}],"version-history":[{"count":0,"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=\/wp\/v2\/pages\/960\/revisions"}],"wp:attachment":[{"href":"https:\/\/wiki.ad-libitum.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=960"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}