PHPの関数内で自己再帰呼び出し
できるかな?と思ってテスト…
<?php function r($count) { echo $count."\n"; if ($count < 10) { r(++$count); } } r(1);
↓
1 2 3 4 5 6 7 8 9 10
でも、関数名を変えると再帰呼び出ししてるところも変えないといけない。
__FUNCTION__を使う
関数内では、__FUNCTION__が関数名を示すので
<?php function r($count) { echo $count."\n"; if ($count < 10) { __FUNCTION__(++$count); } }
ってやった…Parse Error…ですよねー。
一旦変数にする。
<?php function r($count) { $f_name = __FUNCTION__; echo $count."\n"; if ($count < 10) { $f_name(++$count); } }
これはうまくいった。だけど…だけどですよねー。JavaScriptならarguments.callee使えるのになー。
(function(c){ console.log(c++); if (c<10) { arguments.callee(c); } })(1)
PHPのClosureは変数に入れてるしなー。ダメっぽいな。
MovableTypeの$__value__に気をつける。
特殊変数のvalue
ループで使えるんだけど、
<mt:SetHashVar name="month"> <mt:SetVar name="Jan" value="January"> <mt:SetVar name="Feb" value="February"> </mt:SetHashVar> <mt:Loop name="month" sort_by="value"> <li><mt:Var name="__key__">: <mt:Var name="__value__"></li> </mt:Loop>
https://www.movabletype.jp/documentation/appendices/tags/loop.html
なんと、MTContentFieldでも使えるのであった…
<mt:Contents content_type="イベント・セミナー" limit="1"> <mt:ContentField content_field="開催日時"><mt:ContentFieldValue></mt:ContentField> </mt:Contents>
という感じだけど、
<mt:Contents content_type="イベント・セミナー" limit="1"> <mt:ContentField content_field="開催日時"><Var name="__value__"></mt:ContentField> </mt:Contents>
でもいけてしまうのであった…。 https://www.movabletype.jp/documentation/appendices/tags/contentfield.html
Loopの中で_value_使ってた自分、_value_がMTContentFieldで上書きされていることに気づかず無為な時間を過ごしてしまった…
そして、普通に_value_と書くと、はてブではvalueになってしまうのか…_\_value_\_と書かねばならないのだな。
Let's Encryptがまたまたこけてた。
ブログの記事にするのは3回目。
2020-01-14 certbotがまたこけてた - tohokuaikiのチラシの裏
2019-12-09 Debian10でCertbotがこける - tohokuaikiのチラシの裏
なんか、こういうのがあってあんまりクリティカルかつあまりメンテナンスをしないサーバーではLet's Encryptを入れてないんだけど。
エラー内容
こんな感じ
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Processing /etc/letsencrypt/renewal/xxxx.org.conf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Cert is due for renewal, auto-renewing... Plugins selected: Authenticator webroot, Installer None Renewing an existing certificate Performing the following challenges: http-01 challenge for xxxxx.org Cleaning up challenges Attempting to renew cert (xxxx.org) from /etc/letsencrypt/renewal/xxxx.org.conf produced an unexpected error: Missing command line flag or config entry for this setting: Input the webroot for xxxx.org:. Skipping.
なんか、webrootが無いって言われる。なんで今更…
ということで、対応
/etc/letsencrypt/renewal/xxxx.org.conf に
[[webroot_map]] xxxx.org = /var/www/xxxx.org/htdocs
というのを入れてDocumentRootを指定すると上手くいった。
Google AnalyticsのデータをAPI経由で取り出すとか
Google AnalyticsのデータをAPI経由で取り出すとかできるらしい。しかも随分と昔から…Version4ってどんだけ昔からだったんだという…
これに従ってやっていきます。
Google Cloud Platformでプロジェクトを作る
最近のGoogleはみんなGoogle Cloud Platformですわー。
アカウントの追加
でこのプロジェクトを操作できるアカウントを追加する。
ときて
サービス アカウント名とサービス アカウントの説明を入力して作成。
で、このアカウントにロールを付与。とりあえずオーナー入れておけばいいんじゃないのっていう。
で、キーの作成→JSONでキーファイルがダウンロードされる。
これでアカウント追加完了。
Google Analyticsの管理画面で先ほど作成したアカウントに権限を与える
GoogleAnalyticsの管理画面に行き、ビューを選び「管理」の所から「ユーザー管理を表示」を選択。
右上の「+」から先ほど作ったアカウントのメールアドレスを入れる。権限は、「表示と分析」だけでいいでしょう。
PHPのライブラリをインストールして、サンプルを動かす
ファイルの設置
PHPが使えるサーバーに入って、コマンドラインからcomposerを使ってGoogleが提供してるPHPライブラリを
composer require google/apiclient:^2.0
とインストールする。
既にGoogleがサンプルを用意してくれてるので、ここから取得。HelloAnalytics.phpというファイルが得られるのでサーバーに送る。
アカウントのセットアップ
先ほどの「キーを作成」で取得したjsonファイルを service-account-credentials.json としてHelloAnalytics.phpと同じところにアップする。
HelloAnalytics.phpの44行目当たりにある、
<?php function getReport($analytics) { // Replace with your view ID, for example XXXX. $VIEW_ID = "<REPLACE_WITH_VIEW_ID>";
の<REPLACE_WITH_VIEW_ID>を取得する。https://ga-dev-tools.appspot.com/account-explorer/?hl=ja に移動してIDを取得する。
この作業をしたら、HelloAnalytics.phpを動かす。
$ php HelloAnalytics.php PHP Fatal error: Uncaught Google_Service_Exception: { "error": { "code": 403, "message": "Analytics Reporting API has not been used in project 32xxxxxxx8237 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/analyticsreporting.googleapis.com/overview?project=329609518237 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.", "errors": [ { "message": "Analytics Reporting API has not been used in project 32xxxxxxx8237 before or it is disabled. Enable it by visiting https://console.developers.google.com/apis/api/analyticsreporting.googleapis.com/overview?project=329609518237 then retry. If you enabled this API recently, wait a few minutes for the action to propagate to our systems and retry.", "domain": "usageLimits", "reason": "accessNotConfigured", "extendedHelp": "https://console.developers.google.com" } ], "status": "PERMISSION_DENIED" } }
…と、エラーが出る。
URLが表示されるので、アクセスすると
とでるので、「有効にする」を押す。
…と、ここまでで動くようになったけど、なんかデータ取れなかった。
なんか、サンプルのHelloAnalytics.phpがおかしい
このgetReportが
<?php function getReport($analytics) { // Replace with your view ID, for example XXXX. $VIEW_ID = "12345678"; // Create the DateRange object. $dateRange = new Google_Service_AnalyticsReporting_DateRange(); $dateRange->setStartDate("7daysAgo"); $dateRange->setEndDate("today"); // Create the Metrics object. $sessions = new Google_Service_AnalyticsReporting_Metric(); $sessions->setExpression("ga:sessions"); $sessions->setAlias("sessions"); // Create the ReportRequest object. $request = new Google_Service_AnalyticsReporting_ReportRequest(); $request->setViewId($VIEW_ID); $request->setDateRanges($dateRange); $request->setMetrics(array($sessions)); $body = new Google_Service_AnalyticsReporting_GetReportsRequest(); $body->setReportRequests( array( $request) ); return $analytics->reports->batchGet( $body ); }
ってなってるけど、この記事を見ると $dimentionと$orderbyを入れているし…
<?php function getReport($analytics) { // Replace with your view ID, for example XXXX. $VIEW_ID = "88097852"; // $VIEW_ID = "52492899"; // Create the DateRange object. $dateRange = new Google_Service_AnalyticsReporting_DateRange(); $dateRange->setStartDate("7daysAgo"); $dateRange->setEndDate("today"); // Create the Metrics object. $sessions = new Google_Service_AnalyticsReporting_Metric(); $sessions->setExpression("ga:sessions"); $sessions->setAlias("sessions"); $dimention = new Google_Service_AnalyticsReporting_Dimension(); $dimention->setName( 'ga:landingPagePath' ); $orderby = new Google_Service_AnalyticsReporting_OrderBy(); $orderby->setFieldName( "ga:sessions" ); $orderby->setOrderType( "VALUE" ); $orderby->setSortOrder( "DESCENDING" ); // Create the ReportRequest object. $request = new Google_Service_AnalyticsReporting_ReportRequest(); $request->setViewId($VIEW_ID); $request->setDateRanges($dateRange); $request->setMetrics(array($sessions)); $request->setDimensions( array( $dimention ) ); $request->setOrderBys( $orderby ); $body = new Google_Service_AnalyticsReporting_GetReportsRequest(); $body->setReportRequests( array( $request) ); return $analytics->reports->batchGet( $body ); }
これでPHP実行するとパスごとのセッション数が取得できた。
certbotがまたこけてた
certbot renewすると
The requested apache plugin does not appear to be installed. Skipping.
とエラー出して更新してくれない。
ログ /var/log/letsencrypt/letsencrypt.log を見ると
020-01-12 09:32:53,247:WARNING:certbot.renewal:Attempting to renew cert (www.example.jp) from /etc/letsencrypt/renewal/www.example.jp.conf produced an unexpected error: The requested apache plugin does not appear to be installed. Skipping. 2020-01-12 09:32:53,286:DEBUG:certbot.renewal:Traceback was: Traceback (most recent call last): File "/usr/lib/python3/dist-packages/certbot/renewal.py", line 452, in handle_renewal_request main.renew_cert(lineage_config, plugins, renewal_candidate) File "/usr/lib/python3/dist-packages/certbot/main.py", line 1187, in renew_cert installer, auth = plug_sel.choose_configurator_plugins(config, plugins, "certonly") File "/usr/lib/python3/dist-packages/certbot/plugins/selection.py", line 237, in choose_configurator_plugins diagnose_configurator_problem("authenticator", req_auth, plugins) File "/usr/lib/python3/dist-packages/certbot/plugins/selection.py", line 341, in diagnose_configurator_problem raise errors.PluginSelectionError(msg) certbot.errors.PluginSelectionError: The requested apache plugin does not appear to be installed 2020-01-12 09:32:53,286:ERROR:certbot.renewal:All renewal attempts failed. The following certs could not be renewed: 2020-01-12 09:32:53,287:ERROR:certbot.renewal: /etc/letsencrypt/live/www.example.jp/fullchain.pem (failure) 2020-01-12 09:32:53,287:DEBUG:certbot.log:Exiting abnormally: Traceback (most recent call last): File "/usr/bin/certbot", line 11, in <module> load_entry_point('certbot==0.31.0', 'console_scripts', 'certbot')() File "/usr/lib/python3/dist-packages/certbot/main.py", line 1365, in main return config.func(config, plugins) File "/usr/lib/python3/dist-packages/certbot/main.py", line 1272, in renew renewal.handle_renewal_request(config) File "/usr/lib/python3/dist-packages/certbot/renewal.py", line 477, in handle_renewal_request len(renew_failures), len(parse_failures))) certbot.errors.Error: 1 renew failure(s), 0 parse failure(s)
ってなってる。
Apacheのモジュールが必要って、何やねん…って思ったけど、 にあった通り、
したら直った。