PowerCMS X ブログ

2022-08-26

[FAQ] モデルに追加したカラムが投稿画面に表示はされるがデータが保存されない

トラブルの例

記事モデル(entry)に「add_column」という文字列(255)カラムを追加して、編集表示「テキスト」として保存、記事の作成画面を開き、カラムに何らかの文字列を入力して「保存」します。他の既存のカラムには値が保存されているのに、「add_column」には値が保存されていない、という事象です。

確認すべきポイント

error.log に以下のようなメッセージが出ていることを確認します。

PADOBaseModelException: unknown column(entry_add_column) in model entry(1024) occured( line xxx of class.pado.php )

トラブルの原因

cache_driverが「File」になっており、キャッシュディレクトリ配下のファイルに CMS(Webサーバー)から読み込みはできるが、書き込み・削除権限がないことが原因です。定期実行タスク用のスクリプト「tools/worker.php」を root権限などで実行した時に、この事象が発生することがあります。

対応方法

キャッシュディレクトリ配下のファイルを削除して、キャッシュディレクトリをCMS(Webサーバー)から読み書き可能なパーミッションに変更してください。

当該ファイルのパスは以下となりますが、この事象が発生している場合、他のキャッシュファイルの権限も同様になっている可能性がありますので、キャッシュディレクトリ配下ずべてを削除してください。

/path/to/cache/app_cache/schemes/entry.php

尚、CacheManagerが有効で「キャッシュ管理」機能が使える場合でも、この場合はキャッシュ管理の画面からキャッシュのリセットはできません。

sudo rm -Rf /path/to/cache

カテゴリー:技術情報 | トラブルシューティング

投稿者:Junnama Noda

2022-06-14

[FAQ] ユーザーまたはIPアドレスがロックアウトされてしまった時

ユーザー(メンバー)がロックアウトされてしまった場合

パスワードの再設定画面から、メールアドレスを入力、メールに記載のURLでパスワードをリセットするとロックアウトが解除されます。

IPアドレスはロックアウト解除されませんが、環境変数「recover_ip_at_reset」に trueを指定すると、パスワードリセット時に同時にそのIPアドレスを「禁止」→「情報」に変更されます。ただし、IPアドレスを「管理者」に戻すことはできません。

コードを一時的に修正して対応する場合

class.Prototype.php の「admin_protect」「ip_protect」をセットしている場所をコメントアウトします。

                if ( $key === 'administrator_ip' && $cfg->value ) {
                    // $this->admin_protect = true; // ※ 管理者のIP制限
                } else if ( $key === 'allowed_ip_only' && $cfg->value ) {
                    // $this->ip_protect = true; // ※ すべてのユーザーのIP制限
                } else if ( $key === 'timezone' && $cfg->value ) {

データベースを操作する場合

システムの設定画面のロックアウト関係の設定は、テーブル mt_option に option_kind='config' で保存されています。

システムの設定画面のスクリーンショット

option_key 設定名 option_value
two_factor_auth 2段階認証を利用する 0 or 1
lockout_limit ユーザー認証ロック回数 数値 (回数)
lockout_interval ユーザーロックアウト間隔 数値 (秒)
ip_lockout_limit IP認証ロック回数 数値 (回数)
ip_lockout_interval IPロックアウト間隔 数値 (秒)
no_lockout_allowed_ip 許可されたIPアドレスはロックしない 0 or 1
allowed_ip_only 管理者ログインにIPアドレス制限を設定する 0 or 1
administrator_ip すべてのユーザーにIPアドレス制限を適用する 0 or 1

IPアドレスは、mt_remote_ip テーブルに保存されています。これらの値をデータベースを直接操作して変更した場合はキャッシュのクリアが必要となります。

※ cache_driverが”File”の場合、temp_dirの配下もしくは、PowerCMSX/cache/配下にキャッシュファイル群があると思いますので、これらを削除してください。

ver.3.06で追加される環境変数

環境変数「ip_unlock」が追加されます。キーをモデル名( userまたはmember )、値を解除する秒( 数値 )に指定した配列で指定します。指定することで、ロックアウトから一定時間経過した禁止IPアドレスのロックアウトを解除します。

        "ip_unlock" : ["user": 3600, "member": 1800],

カテゴリー:トラブルシューティング | 技術情報

投稿者:Junnama Noda

2022-06-07

ビュー (テンプレート) の記述方法による再構築の軽量化について

PowerCMS Xは、再構築の高速処理を大きな特長の一つとしていますが、データベースのレコードが増えていくにつれて、またビュー (テンプレート) の記述が複雑になっていくにつれ、静的生成・動的生成ともにビューのビルドに時間がかかってくることは従来と変わりません。この記事では、PowerCMS Xならではのビューの記述方法による再構築の軽量化についてのヒントをご紹介します。

計測する

まずは、ページの中のどの部分の処理に時間がかかっているかを計測します。mt:speedmeterブロックタグを使うと便利です。時間がかかっていると思われるオブジェクトのループやループの中でループが呼ばれているなどの部分にあたりを付け、タグで囲ってください。

<mt:speedmeter name="ブロックの名前">
〜
</mt:speedmeter>

このブロックが処理されると、出力ソースの中に以下のHTMLコメントが追加されます。

<!--ブロックの名前 start.-->
〜
<!--ブロックの名前 took 0.7436 seconds to process this block.-->

ブロックは1つのビューに複数指定できますので、部分部分に埋め込んでください。HTMLコメントなので、HTMLで表示するときには影響ないと思われますが、公開中のページにコメントを出力されたくない場合は、プレビューなどでも確認できます。

ループタグの属性指定による利用するカラムの指定

PowerCMS Xでオブジェクトをループ出力するブロックタグ (例 : mt:entries, mt:pages)、リレーション指定されているオブジェクトを出力するブロックタグ (例 : mt:entrycategories, mt:entrytags ) に指定できるタグ属性「cols」を指定します。この属性は、ブロック内で利用されるカラムを絞り込む目的で指定します。

記事のループの指定の例

例えば、記事タイトルと公開日、パーマリンクのみを出力するループでは、以下のように指定します。指定はカンマ区切りテキストか、配列です。

<mt:entries cols="title,published_on">
〜
</mt:entries>

リレーション型、バイナリ型のカラムは指定の必要はありません。このループタグが呼ばれた時に発行されるSQL文は下記となります。

SELECT entry_title,entry_published_on FROM mt_entry ...

※ 実際には以下のカラムは自動的に指定されますが、すべてのカラムを無条件に読み込むことによるオブジェクトの肥大化を避け、軽量・高速に動作させることができます。特に、カラムを多数作成しているモデルでその差は顕著です。

  • id
  • workspace_id
  • status
  • basename

mathタグの代わりに opモディファイアを利用する

ver.2.58より「opモディファイア」が利用可能になりました。テンプレートタグで四則計算が可能になる、という点ではファンクション・タグ「mt:math」と同じですが、opモディファイアのほうがより高速です。また、単純な加算・減算の場合は「incriment」「decriment」モディファイアが利用でき、こちらも mt:mathタグより高速です。

モジュールをキャッシュする

ビューの共通部分を別のモジュールにして mt:includeタグでインクルードしている時、cache_key属性にユニークなキーを渡すことで、モジュールのビルド結果がキャッシュされます。このキャッシュはメモリにキャッシュされ(永続的に保存されず)、index.phpへのリクエストが終わると自動的に破棄されます。ポップアップウィンドウからの再構築時には、一連のリダイレクトが完了するまで保持され、完了すると自動的に破棄されます。

<mt:include module="(Website) HTML Footer" cache_key="ユニークなキャッシュのキー">

ブロック単位でのキャッシュ

モジュールのキャッシュと同様にブロック単位でキャッシュすることができます。以下の指定では、モジュールのキャッシュと同様にメモリにキャッシュされ、index.phpへのリクエスト終了またはポップアップウィンドウからの再構築時には、一連のリダイレクトが完了するまで保持され、完了すると自動的に破棄されます。

<mt:cacheblock cache_key="ユニークなキャッシュのキー">
〜
</mt:cacheblock>

ダイナミックパブリッシング時のキャッシュへの追加属性

ダイナミックパブリッシング (動的生成) ではメモリに保存されたキャッシュは常にリクエストごとに生成・破棄されるため、モジュールやブロックのキャッシュは意味をなしません。以下の属性を追加で指定することができます。以下のブロックは、記事とページの更新があると破棄され、そうでない場合、最大1日キャッシュされます。これらの属性は、mt:includeタグ、mt:cacheblockタグ共通です。

<mt:cacheblock cache_key="ユニークなキャッシュのキー" workspace_id="スペースのID" triggers="entry,page" cache_ttl="86400">
〜
</mt:cacheblock>

以下のブロックは、記事IDが「1」の記事の更新があると破棄され、そうでない場合、最大1日キャッシュされます。

<mt:cacheblock cache_key="ユニークなキャッシュのキー" workspace_id="スペースのID" triggers="entry" cache_object_id="1" cache_ttl="86400">
〜
</mt:cacheblock>

DynamicCachingプラグインの利用

ダイナミックパブリッシング (動的生成) ではページを丸ごとキャッシュさせることができます。キャッシュは再構築トリガーの設定によって破棄され、Membersプラグインにより会員ユーザーがログインして閲覧する場合はキャッシュされません。

共通部分を静的ファイル化してインクルードするか、非同期読み込みする

こちらは静的生成・動的生成共通となります。例えば以下の記事で紹介している「やさにちウォッチ 別ウィンドウで開きます」でランキングを表示させている部分ですが、全てのページで共通であり、1日に1回更新されればよい部分となっています。

このような部分については、静的にインデックス・アーカイブを出力して、mt:includeタグでファイルをインクルードするようにするか、JSON形式で静的ファイルを出力するようなビューを作成して、Ajaxリクエストなどで非同期に読み込むことで、負荷を軽減でき、ページ表示速度も速くすることができます。

DBのチューニングや再構築の並列処理などの選択肢

ループのフィルタに利用しているカラムには「インデックス」を指定する

ループのタグでリレーション(記事に対するカテゴリやタグ)以外の、モデルの標準カラムでフィルタリングして出力する時は、そのカラムに「インデックス」を指定することで高速化するいことができます。以下の例では、記事に「filter」というカラムを追加して、その値でフィルタリングしている例です。

<mt:entries filter="値">
〜
</mt:entries>

この記事ではビュー (テンプレート) に絞ってご紹介したため、その他の高速化手法については改めて纏めてご紹介します。

ブログ内検索

アーカイブ