[concrete5]悲劇的!Designer Contentの落とし穴

結論

いきなり結論です。

Designer contentを使用してブロックを作成し、間違えて作成したブロックを削除する際には、
「FTP上のblock/”Dir”」と、「データベース内のblocktypeにある”Dir”」の両方を削除してください。
※”Dir”はブロックタイプ作成時の任意です。

実ファイルとデータベースのテーブルを削除しないと思わぬエラーの原因となります。

なお、以下は今日起こった現象の振り返りなので、あまり意味がありませんのであしからず。

ブロックが追加出来ないよ!?

本日、concrete5をご利用のクライアントのサーバー移行作業を行っていた所、「ブロック追加」が一切機能しなくなりました。
「あれれー、おかしいなぁー」と思い、管理画面からブロックタイプを開こうとした所、Internal Server Error 500との事。

はてさて、一体何なんでしょうか。
何はなくともエラーログを見る習慣付けは必要だと思いました。全く関係のないアドオンを消したりしてまた入れ直したり、とても面倒な事をしてしまいました。
エラーログを拝見いたしました所、2つのエラーの記録がございました。

エラーの内容

[code]
[error] [client xxx.x.x.x] PHP Warning: require_once(/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.php): failed to open stream: No such file or directory in /home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/core/libraries/loader.php on line 205, referer: http://xxx.xxx.xxx.xx/index.php/dashboard/

[error] [client 219.8.4.64] PHP Fatal error: require_once(): Failed opening required ‘/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.php’ (include_path=’/home/httpd/public_html/libraries/3rdparty:/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/libraries/3rdparty:.:/usr/share/pear:/usr/share/php’) in /home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/core/libraries/loader.php on line 205, referer: http://xxx.xxx.xxx.xx/index.php/dashboard/
[/code]

サーバー移行と同時にconcreteのアップデートも行ったのですが、アップデート前は問題なく利用出来てたというところがポイントです。

で。

エラーの内容は、「そもそも/home/httpd/public_html/updates/concrete5.6.0.2.ja/concrete/blocks/links/controller.phpってファイルがおかしいじゃんか、無いじゃんかー。」って仰るわけです。
私としましても、「うーん、そんなブロックは使ってないよなぁー。」と頭を抱えるしかございませんでした。

救世主は移行前のサイトでした

Designer contentは非常に便利なアドオンで、ブロックの内容を自由に組み立てる事ができます。
ただ、弱点が一つあって、Designer contentでブロック作成をする際に、内容を間違えて登録してしまった時です。
間違えて登録してしまった後に、管理画面から修正を行おうとしても出来ないという弱点があって、簡単に順番の入れ替えや、静的タグの追加くらいなら、直接生成されたphpファイルをいじれば直せるのですが、テキストフィールドの追加を忘れてしまった場合は別のブロックタイプをDesigner contentで新たに作成し直すしかないのです(一応方法はあるのでしょうが、私はphpに詳しくないので作り直した方が速い。)

そう、過去の負の遺産が残っておりました。

間違えて作成してしまったブロックタイプを、FTPからディレクトリごと削除していました。
移行前の方では、ディレクトリが存在していないにも関わらず、動作していました。

でも、データベースには作成したブロックタイプは残っているので、concreteのcoreにある「/concrete/core/libraries/loader.php」は居なくなってしまった「/block/links」を探し続けてしまいます。

ここからは推測ですが、管理画面からアップデートをかけた際に、concreteのcoreファイルのパスが変わる関係で、アップデート前ではディレクトリが無くてもごまかして動いていたものが、動かなくなってしまったと考えています。

Designer contentを使用してブロックを作成し、間違えて作成したブロックを削除する際には、
「FTP上のblock/”Dir”」と、「データベース内のblocktypeにある”Dir”」の両方を削除してください。
※”Dir”はブロックタイプ作成時の任意です。

[メモ]Concrete5のマルチアップロードでError: 401

どないなっとんねん!怒るでしかし!!

という冗談はさておき、Concrete5のファイルマネージャーは非常に便利です。
強力なファイルの検索はもちろんの事、複数のファイルをセットにまとめて、スライドショーで利用したり、一度に複数のファイルをアップロードしたり…etc

で。

特定の条件でマルチアップロードが動かなくなります。

こんなふうに。

理由としては下記の様にいくつか考えられますが、どれも該当しなかったので。

  • /filesとそれ以下のすべてのディレクトリの権限が755になってない
  • /filesとそれ以下のすべてのディレクトリの所有者がapache以外になってる
  • ファイルサイズがphp.iniに書かれているサイズよりも大きい

じゃー、なんなのさって話で。

リリース前の段階って事で、普段納品前は、サイトの閲覧権限を「管理者」のみに設定してクライアントに確認してもらってるんだけど、諸事情で基本認証かけたんですよ。

そう!
聡明な皆様ならもう、お気づきですね!「この先は、言わなくてもわかりますよね?」とは言いませんが。

基本認証がどうやら邪魔しているらしく。
つまり、concrete5ではベーシック認証なんかかけなくても、管理画面から簡単に公開非公開選べるんだから、それでやれ、という事だと受け取っておきます。

[CSSクイズ]構造を変えずにCSSだけでボックスの上下の順番を入れ替えられるのかッ!?

<div id="content">
  <div id="firstBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
  <div id="secondBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
  <div id="thirdBox">
    <p>テキストテキストテキストテキスト</p>
  </div>
</div>

例えば上記のHTMLがあったとして。
下記の図のように、#secondBoxと#thirdBoxの位置を入れ替えたいんですよ。

で、条件としては以下。

  • 各div内のテキスト量は不定。つまり高さは可変
  • HTML構造を変えてはダメ
  • CSSはいくらでもいじっても良し

なんだかんだでね、これ結構難しい問題だと思うんですよ。
解決策がない。
CSSクイズとか表題にしてるくせにさ、答えがないんですよ。

position: absolute使うにしても、ボックスの高さが不定だからtopもしくはbottomの値が定まらないし、同様にネガティブマージン使うにしても値が決まらない。
もう#thirdBoxにheight決め打ちしちゃってoverflow: hiddenかscrollでって事も考えた。

なんかどれもこれもスマートじゃない。スマートフォン向けに作ってるのに、全然スマートじゃない!!
あ、このフレーズいいな。今度から打ち合わせとかで使おう。「それ全然スマートじゃないですよね?スマートフォン向けなのに、全然スマートじゃないですよね?」って。

閑話休題。
で、結論としては、もうCSSだけじゃ解決できないよ私。
助けてjavascript〜!

こうすることにした。※cssの部分は結構省略して書いてます。

CSS

div#content {
  position: relative;
}
div#content div#secondBox {
  position: absolute;
}
div#content div#thirdBox {
  position: relative;
}

javascript

[javascript]
var fitstHeight =$(‘#firstBox’).height(); //高さを取得
var secondHeight =$(‘#secondBox’).height(); //高さを取得
var thirdHeight =$(‘#thirdBox’).height(); //高さを取得

$(‘#content’).css(‘height’, fitstHeight + secondHeight + thirdHeight); //#contentに中身のボックスの高さを合計した値を与える。
$(‘#secondBox).css(‘top’, fitstHeight + thirdHeight); //#secondBoxのtopからの位置を#firstBoxと#thirdBoxの合計した値を与える。
[/javascript]

でも、結局javascriptで解決するのも、なんだかちっともスマートじゃないですね。
この部分の解決策は多分、html原理主義者か、js信徒か、css教徒の三つどもえの論争が終わらないんじゃないかなぁと思います。

「君のやり方は間違っている!俺の解決方法はこれだッ!!」って思う人はご遠慮なさらずコメント欄へどうぞ。

メモ:concrete5で親ページのタイトルを取得

どうしても親ページのタイトルを表示しないと死んでしまうんです!!

で、いろいろ調べた。テーマファイルにこれを書けば出てくるみたい。

<?php 
$parent = Page::getByID($c->getCollectionParentID());
echo $parent->getCollectionName();
?>

メモ:concrete5のページ属性で指定した画像を表示する方法

concrete5のページ属性に入力した情報は、
[code]
$c->getAttribute(‘ハンドル’)
[/code]
で取得できます。

単純にテキストを出すだけなら下記のように取り出せば良いだけなんだけど、

<h1><?php echo $c->getAttribute('ハンドル');?></h1>

画像の場合はわかりにくかった。下記の様に書けばokです。

<img src="<?php echo ($c->getAttribute('ハンドル')->getVersion()->getRelativePath());?>" alt="" />

ターミナルでディレクトリの削除

EC-CUBEのインストールディレクトリを間違えたので、filezillaで一旦htmlディレクトリを全部削除しようと思ったらなぜかできなかった。

ターミナルで以下のコマンド書いたら「ディレクトリです」って。

$ rm html
rm: cannot remove `html': ディレクトリです

どうやら書き込み保護されているとディレクトリの削除ができないらしい。
こういう場合は、「-r」オプションをつけるといいらしくて。

$ rm -r html
rm: 書き込み保護されたファイル `html/xxxxx.html' を削除しますか(yes/no)? no
rm: ディレクトリ ``html'' を削除できません: ディレクトリは空ではありません

それでも削除できない場合は、「-f」オプションで強制的に削除できました。

$ rm -rf html

やったね!