{"id":22051,"date":"2022-05-15T20:36:34","date_gmt":"2022-05-15T18:36:34","guid":{"rendered":"https:\/\/notiz.blog\/?p=22051"},"modified":"2024-03-08T16:00:28","modified_gmt":"2024-03-08T15:00:28","slug":"wpsr","status":"publish","type":"post","link":"https:\/\/notiz.blog\/2022\/05\/15\/wpsr\/","title":{"rendered":"WPSR"},"content":{"rendered":"\n<p>Auf dem <a href=\"https:\/\/www.cloudfest.com\/hackathon\" data-type=\"URL\" data-id=\"https:\/\/www.cloudfest.com\/hackathon\">CloudFest Hackathon<\/a> im M\u00e4rz, hab&#8216; ich mich ein wenig mit <a href=\"https:\/\/www.alainschlesser.com\/\" data-type=\"URL\" data-id=\"https:\/\/www.alainschlesser.com\/\">Alain Schlesser<\/a> \u00fcber WordPress und Plugin-Entwicklung unterhalten. Alain meinte, dass er, wenn es das Plugin hergibt und es zeitlich m\u00f6glich ist, immer zuerst eine generische Library bauen und diese dann \u00fcber ein WordPress-Plugin implementieren w\u00fcrde.<\/p>\n\n\n\n<p>Vor ein paar Tagen hab ich mich an unser Gespr\u00e4ch erinnert, weil ich mich (aus Gr\u00fcnden) wieder intensiver mit dem <a href=\"https:\/\/wordpress.org\/plugins\/activitypub\/\" data-type=\"URL\" data-id=\"https:\/\/wordpress.org\/plugins\/activitypub\/\">ActivityPub-Plugin<\/a> besch\u00e4ftigt habe. Wir hatten schon vor einem Jahr den Plan, eine <a href=\"https:\/\/github.com\/landrok\/activitypub\/\" data-type=\"URL\" data-id=\"https:\/\/github.com\/landrok\/activitypub\/\">ActivityPub-Bibliothek<\/a> zu verwenden, um uns nicht mit dem Protokoll besch\u00e4ftigen zu m\u00fcssen, und uns so voll und ganz auf die WordPress Integration konzentrieren k\u00f6nn(t)en. Wir haben die Idee aber erstmal nicht weiter verfolgt, da die Bibliothek eine Reihe von schwergewichtigen <a href=\"https:\/\/github.com\/landrok\/activitypub\/blob\/master\/composer.json#L9\" data-type=\"URL\" data-id=\"https:\/\/github.com\/landrok\/activitypub\/blob\/master\/composer.json#L9\">Third-Party-Libs<\/a> wie <a href=\"https:\/\/github.com\/guzzle\/guzzle\" data-type=\"URL\" data-id=\"https:\/\/github.com\/guzzle\/guzzle\">Guzzle (HTTP-Client)<\/a>, <a href=\"https:\/\/github.com\/Seldaek\/monolog\" data-type=\"URL\" data-id=\"https:\/\/github.com\/Seldaek\/monolog\">Monolog (Logger)<\/a> oder <a href=\"https:\/\/github.com\/symfony\/cache\" data-type=\"URL\" data-id=\"https:\/\/github.com\/symfony\/cache\">Symfony Cache (Caching)<\/a> mit sich bringt. F\u00fcr all diese Funktionen hat WordPress eigene L\u00f6sungen und wegen der Interoperabilit\u00e4t mit anderen Plugins, sollte man diese auch nutzen.<\/p>\n\n\n\n<p>Bei der erneuten Evaluierung der ActivityPub-Bibliothek ist mir aufgefallen, dass sich Monolog, durch einen beliebigen PSR-3 kompatiblen Logger ersetzen l\u00e4sst.<\/p>\n\n\n\n<p>Kurze Erkl\u00e4rung zu <a href=\"https:\/\/www.php-fig.org\/psr\/\" data-type=\"URL\" data-id=\"https:\/\/www.php-fig.org\/psr\/\">PSR<\/a>:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Eine PHP Standard Recommendation (PSR) ist eine PHP-Spezifikation, welche durch die PHP Framework Interop Group ver\u00f6ffentlicht wird. \u00c4hnlich einem Java Specification Request in Java dient sie der Standardisierung von Programmierkonzepten. Ziel ist es die Interoperabilit\u00e4t von Komponenten zu erm\u00f6glichen und eine gemeinsame technische Basis zu schaffen oder bew\u00e4hrte Konzepte f\u00fcr einen guten Programmierstil sowie eine gute Testbarkeit von Komponenten umzusetzen. Verschiedene Frameworks wie z. B. die der TYPO3-Community, Symfony oder Zend implementieren hierbei PSR-Spezifikationen in einem selbst gew\u00e4hlten Umfang.<\/p>\n<cite><a href=\"https:\/\/de.wikipedia.org\/wiki\/PHP_Standard_Recommendation\">https:\/\/de.wikipedia.org\/wiki\/PHP_Standard_Recommendation<\/a><\/cite><\/blockquote>\n\n\n\n<p><a href=\"https:\/\/www.php-fig.org\/psr\/psr-3\/\" data-type=\"URL\" data-id=\"https:\/\/www.php-fig.org\/psr\/psr-3\/\">PSR-3<\/a> definiert ein standardisiertes Logger-Interface, welches (in unserem Beispiel) durch Monolog implementiert wird. Beim initialisieren des ActivityPub-Servers, l\u00e4sst sich Monolog, durch einen alternativen Logger ersetzen, solange dieser auch PSR-3 konform ist.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">ActivityPhp<\/span>\\<span class=\"hljs-title\">Server<\/span>;\n\n<span class=\"hljs-comment\">\/\/ Create a server instance with no log output<\/span>\n$server = <span class=\"hljs-keyword\">new<\/span> Server(&#91;\n    <span class=\"hljs-string\">'logger'<\/span>   =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'\\Psr\\Log\\NullLogger'<\/span>\n    ],\n]);<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Also hab ich mir \u00fcberlegt, wie so ein Logger f\u00fcr WordPress aussehen k\u00f6nnte und einen <a href=\"https:\/\/github.com\/pfefferle\/wp-psr-log\" data-type=\"URL\" data-id=\"https:\/\/github.com\/pfefferle\/wp-psr-log\">PSR-3 kompatiblen Wrapper gebaut:<\/a><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">namespace<\/span> <span class=\"hljs-title\">WPPSR<\/span>\\<span class=\"hljs-title\">Log<\/span>;\n\n<span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">Psr<\/span>\\<span class=\"hljs-title\">Log<\/span>\\<span class=\"hljs-title\">AbstractLogger<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ErrorLogLogger<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">AbstractLogger<\/span> <\/span>{\n    <span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">log<\/span><span class=\"hljs-params\">( $level, $message, $context = array<span class=\"hljs-params\">()<\/span> )<\/span> <\/span>{\n        <span class=\"hljs-keyword\">if<\/span> ( defined( <span class=\"hljs-string\">'WP_DEBUG'<\/span> ) &amp;&amp; WP_DEBUG ) {\n            <span class=\"hljs-keyword\">if<\/span> ( defined( <span class=\"hljs-string\">'WP_DEBUG_LOG'<\/span> ) &amp;&amp; WP_DEBUG_LOG ) {\n                error_log(\n                    sprintf(\n                        <span class=\"hljs-string\">'%s: %s. Details: %s'<\/span>,\n                        $level,\n                        trim( $message, <span class=\"hljs-string\">'.'<\/span> ),\n                        json_encode( $context )\n                    )\n                );\n            }\n        }\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code-Sprache:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>PSR definiert passenderweise auch Interfaces f\u00fcr HTTP-Clients, Request-\/Response-Objekte und Caching. F\u00fcr die Request-Library die in WordPress benutzt wird, gibt es sogar schon ein passendes Issue: <a href=\"https:\/\/github.com\/WordPress\/Requests\/issues\/320\">https:\/\/github.com\/WordPress\/Requests\/issues\/320<\/a><\/p>\n\n\n\n<p>Leider sind Caching und der HTTP-Client in der ActivityPub-Implementierung noch nicht austauschbar, obwohl beide benutzten Libraries PSR kompatibel sind. Das hei\u00dft ich muss zuerst evaluieren, wie viel Arbeit es ist, die ActivityPub-Lib anzupassen, um dann diverse Wrapper f\u00fcr das WordPress Caching und die Request-\/Response-Classes zu schreiben&#8230;<\/p>\n\n\n\n<p>Bzw. muss ich das wahrscheinlich nicht einmal selbst implementieren, da ich bei weitem nicht der Erste war, der diese Idee hatte:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/packagist.org\/packages\/inpsyde\/wpsr7\">WPSR7<\/a> von Inpsyde<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/felixarntz\/wp-psr-cache\" data-type=\"URL\" data-id=\"https:\/\/github.com\/felixarntz\/wp-psr-cache\">wp-psr-cache<\/a> von Felix Arntz<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/thegallagher\/wordpress-psr-cache\">wordpress-psr-cache<\/a> von David Gallagher<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/RebelCode\/wp-http\">wp-http<\/a> von RebelCode<\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/search?p=1&amp;q=wordpress+psr&amp;type=Repositories\" data-type=\"URL\" data-id=\"https:\/\/github.com\/search?p=1&amp;q=wordpress+psr&amp;type=Repositories\">uvm.<\/a><\/li>\n<\/ul>\n\n\n\n<p>WordPress tut sich immernoch schwer mit modernem PHP-Dependency-\/Plugin-Management. Ersteres ist praktisch nicht vorhanden (<a href=\"https:\/\/developer.yoast.com\/blog\/composer-dependencies-in-wordpress-plugins\/\" data-type=\"URL\" data-id=\"https:\/\/developer.yoast.com\/blog\/composer-dependencies-in-wordpress-plugins\/\">wird aber zumindest nicht verhindert<\/a>) und letzteres basiert immer noch auf einem Prozess in dem SVN eine tragende Rolle spielt. Aber mit PSR(-Wrappern) kann man das Problem schon ganz gut kompensieren \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Auf dem CloudFest Hackathon im M\u00e4rz, hab\u2018 ich mich ein wenig mit Alain Schlesser \u00fcber WordPress und Plugin-Entwicklung unterhalten. Alain meinte, dass er, wenn es das Plugin hergibt und es zeitlich m\u00f6glich ist, immer zuerst eine generische Library bauen und diese dann \u00fcber ein WordPress-Plugin implementieren w\u00fcrde.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"webmentions_disabled_pings":false,"webmentions_disabled":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":4,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"federated","footnotes":""},"categories":[946],"tags":[1153,5171,1177,1176,181,1175,57],"class_list":{"0":"post-22051","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-wordpress","7":"tag-projekt26","8":"tag-fediblog","9":"tag-php","10":"tag-php-fig","11":"tag-plugin","12":"tag-psr","13":"tag-wordpress","14":"h-entry","15":"hentry"},"_links":{"self":[{"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/posts\/22051","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/comments?post=22051"}],"version-history":[{"count":5,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/posts\/22051\/revisions"}],"predecessor-version":[{"id":25049,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/posts\/22051\/revisions\/25049"}],"wp:attachment":[{"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/media?parent=22051"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/categories?post=22051"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/notiz.blog\/wp-api\/wp\/v2\/tags?post=22051"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}