忍者ブログ
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。



2026/04/10 20:20 |
Symfony-7日目その3
現在Programmingカテゴリには有効な求人が32件ありますが、カテゴリページでも先頭10件しか表示されず、続きを見ることができません。
早速ページング処理してみます。

まずapp.ymlに1ページあたりの表示件数を記述。
config/app.yml
1
2
all:
  max_jobs_on_category: 20

チュートリアルではapps/frontend/config/app.ymlに書くようになっていますがどちらでもいいです。

apps/frontend/modules/category/actions/actions.class.php
1
2
3
4
5
6
7
8
9
10
11
public function executeShow(sfWebRequest $request){
  $this->category = $this->getRoute()->getObject();
 
  $this->pager = new sfDoctrinePager(
    'JobeetJob',
    sfConfig::get('app_max_jobs_on_category')
  );
  $this->pager->setQuery($this->category->getActiveJobsQuery());
  $this->pager->setPage($request->getParameter('page', 1));
  $this->pager->init();
}

sfDoctrinePagerがページャーオブジェクトです。
setQuery()でクエリオブジェクトを突っ込むとページング処理を行ってくれます。
JobeetCategory::getActiveJobsQuery()はまだ無いので作成します。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
public function getActiveJobsQuery(){
  $q = Doctrine_Query::create()
    ->from('JobeetJob j')
    ->where('j.category_id = ?', $this->getId());
  return Doctrine::getTable('JobeetJob')->addActiveJobsQuery($q);
}

やってることはJobeetCategory::getActiveJobs()とほぼ同じで、実際にクエリを実行してしまうかクエリオブジェクトをそのまま持ってくるかの違いしかありません。
ということでリファクタリングできます。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
7
public function getActiveJobs($max = 10){
  $q = $this->getActiveJobsQuery()->limit($max);
  return $q->execute();
}
public function countActiveJobs(){
  return $this->getActiveJobsQuery()->count();
}

JobeetCategory::getActiveJobsQuery()はクエリオブジェクトをそのまま返し、countActiveJobs()は取得できる件数を返し、getActiveJobs()は実際にその内容を取得して返します。

最後にテンプレートを更新。
ページング関連を追加します。

apps/frontend/modules/category/templates/showSuccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php use_stylesheet('jobs.css') ?>
 
<?php slot('title', sprintf('Jobs in the %s category', $category->getName())) ?>
 
<div class="category">
  <div class="feed">
    <a href="">Feed</a>
  </div>
  <h1><?php echo $category ?></h1>
</div>
 
<?php include_partial('job/list', array('jobs' => $pager->getResults())) ?>
 
<?php if ($pager->haveToPaginate()): ?>
  <div class="pagination">
    <a href="<?php echo url_for('category', $category) ?>?page=1">
      <img src="/images/first.png" alt="First page" title="First page" />
    </a>
 
    <a href="<?php echo url_for('category', $category) ?>
      ?page=<?php echo $pager->getPreviousPage() ?>">
      <img src="/images/previous.png" alt="Previous page" title="Previous page" />
    </a>
 
    <?php foreach ($pager->getLinks() as $page): ?>
      <?php if ($page == $pager->getPage()): ?>
        <?php echo $page ?>
      <?php else: ?>
        <a href="<?php echo url_for('category', $category) ?>
          ?page=<?php echo $page ?>"><?php echo $page ?></a>
      <?php endif; ?>
    <?php endforeach; ?>
 
    <a href="<?php echo url_for('category', $category) ?>
      ?page=<?php echo $pager->getNextPage() ?>">
      <img src="/images/next.png" alt="Next page" title="Next page" />
    </a>
 
    <a href="<?php echo url_for('category', $category) ?>
      ?page=<?php echo $pager->getLastPage() ?>">
      <img src="/images/last.png" alt="Last page" title="Last page" />
    </a>
  </div>
<?php endif; ?>
 
<div class="pagination_desc">
  <strong><?php echo $pager->getNbResults() ?></strong>
     jobs in this category
  <?php if ($pager->haveToPaginate()): ?>
    - page <strong><?php echo $pager->getPage() ?>
                  /<?php echo $pager->getLastPage() ?></strong>
  <?php endif; ?>
</div>

なんだこのややこしいテンプレートは。
こんな訳の解らないものを出して「ロジックとデザインの分離が出来た!」とか言ってる場合じゃないと思うんだが。
こんなの絶対デザイナーには触れない。
あとどうでもいいけどチュートリアルのテンプレはFirstpageにtitleが無い。

やってることを順に解説すると、まずsfDoctrinePager::haveToPaginate()でページングの必要があるかどうか判断。
その後は、1ページ目へのリンク、前のページへのリンク、各ページへの順番リンク、次のページへのリンク、最後のページへのリンクを順に書いているだけです。
ちなみにsfDoctrinePager::getLinks()で返ってくるのは単なる数値の配列です。


非常に残念なのがリンクを自力で書かなければならないこと。
Pear::PagerCakePHPZend_Paginatorといった主なページャーはここらへんを自動でやってくれるので、これらに比べると使い勝手の悪さが目立ちます。
せっかくのフルスタックフレームワークなんだからurl_for('category', $pager->next())くらいやってほしかった。

てーかそこらへんリファレンスで何一つ解説されてないとか酷すぎる。


Symfonyの記事一覧
PR


2010/01/18 22:36 | Comments(0) | TrackBack() | PHP
買ったものリスト 2010/01/17

ていうか最近漫画ばっかりだな。
前はもっとまともな本も読んでたんだよ。
最近漫画ばかりなのはあれだ、よく行く本屋がコミック売り場だけ別の建物に隔離されてるせいなんだ。
おかげでコミックコーナー行って力尽きる。
やはり本屋はヨドバシ博多みたいなワンフロア形式がいい。


デュラララ!!4
☆☆☆☆

珍しく臨也がハブられてる話。
なんで毎回強キャラは人格破綻者ばっかりなんでしょうか。


あやしい男と失恋ってきました。
☆☆☆

痛い男に痛い女総出演の痛い漫画。
なんだけど、残念ながら私には全く縁のない世界の話なのでさっぱりわからない。
ああ、世界にはこんな人がいるんだなあ、というかこんな世界があるんだなあという生態を見てみるには最適。


数学ガール上
☆☆☆

椅子を蹴るなよ。

ということでよくわからんかった。
いやまあ数式はわかるんだけど、ミルカさんの性格が特異すぎてよくわからん。
個人的にはテトラちゃんのほうが良い。


BTOOOM!2
☆☆☆

吉良との戦闘は他と違って如何にもフィクションな戦闘だったので逆に違和感があった。
あとガスタイプ性能高過ぎじゃね?
まあ、あんな環境で女の子がどうなるかなんて考えるまでもないわな。


9時間9人9の扉

やーっっっっっっと売ってるの見つけた。
なんでこんなにレアなんだ。
現在2周目ですがいかにも打越っぽいネタが隠されてそうな感じで楽しみだ。
 



2010/01/17 17:52 | Comments(0) | TrackBack() | 買ったもの
9時間9人9の扉 プレイ日記2
9時間9人9の扉 プレイ日記2

※ネタバレを含むので未プレイの方は閲覧をご遠慮ください。


2010/01/16 13:20 | Comments(0) | TrackBack() | ゲーム
Symfony-7日目その2
リンクを張るほうがようやく完成したので、次はリンク先を作成します。
リンク先はcategoryモジュールという別個のモジュールにしてしまうので、とりあえずコマンドラインから骨組みを作成します。
> php symfony generate:module frontend category


次に前回url:slugとか書いていた部分に対してその実体を作成します。

>categoryテーブル用にslugカラムを追加する必要があります:
>このslugカラムはDoctrineのSluggableビヘイビアによって考慮されます。
>JobeetCategoryモデルのビヘイビアを有効にすればすべてが考慮されます。


駄目だ、何度読んでも意味がわからない。

Doctrineのドキュメントでようやくそれっぽい記述を発見しました。
スキーマにテーブル名:actAs:Sluggable:というオプションを記述しておけば、テーブル自体にはカラムを作成しないけどモデル的にはカラムが存在するように振る舞う、というような内容のようです。

あと、"Sluggable ビヘイビア"でようやくslugの意味がわかったわ。
 何故Doctrineのサイト自身にこれを適用していないんだろう?


スキーマファイル、JobeetCategory:actAs:内に以下を追加します。
config/doctrine/schema.yml
1
2
3
4
JobeetCategory:
  actAs:
    Sluggable:
      fields: [name]


スキーマを書き換えたのでデータベースを作り直します。
例によって直接DBを触った内容は全削除されます。
>php symfony doctrine:build-all-reload --no-confirmation

1
2
3
4
5
6
7
8
9
10
CREATE TABLE IF NOT EXISTS `jobeet_category` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `slug` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`),
  UNIQUE KEY `sluggable_idx` (`slug`)) ENGINE=InnoDB  DEFAULT CHARSET=utf8 ;

slugフィールドが作成されていました。なんだそれ。

この定義により、JobeetCategory::save()メソッド等で保存を行った際、jobeet_category.nameをslugifyした結果が勝手にslugフィールドに入るようになります。

さて、slugフィールドが実在するようになったので、今日スキーマに書いた
url: /category/:slug
の:slugは実在のカラムを参照できるようになり、せっかく書いたJobeetCategory::getSlug()は不要となります。
あったとしても元のメソッドがオーバーライドされるだけですが、まあ意味がないので削除しましょう。


ようやく画面表示コントローラとテンプレートの作成です。
ルーティングでparam: {module: category,action: show }と定義しているのでcategoryActions::executeShow()が呼び出されます。

apps/frontend/modules/category/actions/actions.class.php
1
2
3
public function executeShow(sfWebRequest $request){
  $this->category = $this->getRoute()->getObject();
}


apps/frontend/modules/category/templates/showSuccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php use_stylesheet('jobs.css') ?>
<?php slot('title', sprintf('Jobs in the %s category', $category->getName())) ?>
<div class="category">
  <div class="feed">
    <a href="">Feed</a>
  </div>
  <h1><?php echo $category ?></h1>
</div>
<table class="jobs">
  <?php foreach ($category->getActiveJobs() as $i => $job): ?>
    <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
      <td class="location">
        <?php echo $job->getLocation() ?>
      </td>
      <td class="position">
        <?php echo link_to($job->getPosition(), 'job_show_user', $job) ?>
      </td>
      <td class="company">
        <?php echo $job->getCompany() ?>
      </td>
    </tr>
  <?php endforeach; ?>
</table>


ようやくカテゴリ単位で閲覧を行えるようになりました。
なにげに10件しか表示されていないのですが、それはまた今度。
先にパーシャルテンプレートを解説します。

テンプレートをよく見てみると、apps/frontend/modules/job/templates/indexSuccess.phpapps/frontend/modules/category/templates/showSuccess.php<table class="jobs">
の中身は全く同じです。
こういう場合、共通する部分だけ別のファイルに書き出して共有を行うことができます。

apps/frontend/modules/job/templates/_list.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<table class="jobs">
  <?php foreach ($jobs as $i => $job): ?>
    <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
      <td class="location">
        <?php echo $job->getLocation() ?>
      </td>
      <td class="position">
        <?php echo link_to($job->getPosition(), 'job_show_user', $job) ?>
      </td>
      <td class="company">
        <?php echo $job->getCompany() ?>
      </td>
    </tr>
  <?php endforeach; ?>
</table>


include_partial()でインクルードを行うことができます。
<?php include_partial('job/list'); ?>とすると、jobモジュール内のlistテンプレート、すなわちapps/frontend/modules/job/templates/_list.phpがそのまま取得できます。
注意点としては、変数はそのままでは全く渡されないということです。
上記apps/frontend/modules/category/templates/showSuccess.phpから単にinclude_partial('job/list');としただけでは、_list.php内の$jobsは空っぽです。
共通して変数を使いたい場合は、第二引数で渡す必要があります。

よって、上記showSuccess.phpのテーブル表示部分はこのようになります。
apps/frontend/modules/category/templates/showSuccess.php
1
<?php include_partial('job/list', array('jobs' => $category->getActiveJobs())) ?>


トップ画面の方も修正しましょう。
apps/frontend/modules/job/templates/indexSuccess.php
1
2
3
<?php include_partial('job/list', 
  array('jobs' => $category->getActiveJobs(
   sfConfig::get('app_max_jobs_on_homepage'))))

ちなみにトップ画面の場合、同じモジュール内にあるのでモジュール名を省略してinclude_partial('list')と書くこともできます。


Symfonyの記事一覧


2010/01/15 23:13 | Comments(0) | TrackBack() | PHP
9時間9人9の扉 プレイ日記1
9時間9人9の扉 プレイ日記1

※ネタバレを含むので未プレイの方は閲覧をご遠慮ください。


2010/01/14 23:22 | Comments(0) | TrackBack() | ゲーム
ALTが突然変異
何故かALTが突然変異。
20100113-blood


採血日 2009/12/30 2009/12/06 2009/11/07 2009/09/23 2009/08/16
ALT(GPT) 41 17 13 17 19
γ-GTP 21 14 17 15 16
TP 7.6 7.8 7.7 7.8 7.5
ALB 4.3 4.4 4.5 4.5 4.4
A/G 1.3 1.3 1.4 1.3 1.4
CHOL 162 171 169 173 187
GA 13.5 13.9 14.2 14.3 14.3
RBC 493 481 482 509 508
Hb 14.1 14.0 13.7 13.9 14.9
Ht 43.1 41.1 41.7 43.9 43.4
MCV 87.4 85.4 86.5 86.2 85.4
MCH 28.6 29.1 28.4 27.3 29.3
MCHC 32.7 34.1 32.9 31.7 34.3
WBC 62 63 82 71 74
PLT 31.2 25.9 27.4 27.6 30.7

一体俺の体に何が!
と思ったら標準値が5~45で何気に問題無い値だった。


2010/01/13 22:29 | Comments(0) | TrackBack() | 戯言
Symfony-7日目その1
十分な時間なんてなかったので何もせずに7日目スタート。

まず、カテゴリ宛へのリンクでやってきた場合のルーティングを定義します。

apps/frontend/config/routing.yml
1
2
3
4
5
category:
  url:      /category/:slug
  class:    sfDoctrineRoute
  param:    { module: category, action: show }
  options:  { model: JobeetCategory, type: object }

だからslugって何なんだよ。

とりあえず以上のルーティングで下記のようなURLに合致することになります。
http://symfony.localhost/frontend_dev.php/category/hoge
categoryモジュールのshowアクションが実行されます。

>ルートは関連オブジェクトからの任意のカラムをパラメーターとして使うことができます。
>オブジェクトクラスで定義された関連アクセサーが存在する場合、ルートは他の値も使用できます。
>slugパラメーターは対応するcategoryテーブルのカラムを持たないので、ルートを動作させるためにJobeetCategoryのバーチャルアクセサーを追加する必要があります:

何この日本語。

解読すると、どうやらルーティングのurl:パラメータに、options:model:のモデルで指定されているカラムが存在しない場合、モデルにあるgetメソッドを実行する、ということのようです。
というか、全てのurl:パラメータに対してgetメソッドを実行してるんだけど、カラムが存在しているパラメータに対してのgetメソッドは最初から存在するので実装する必要が無く、存在しないカラムの場合は書かないといけないよ、ということのようです。

さてポイントは、これらはcategory:に合致するURLにやってきたときに動作するのではなく、テンプレートからcategoryを使用したURLへのリンクを作成しようとした際に動作するということです。
リンク先に移動したときではなく、リンクを表示するときに必要だったわけですね。
7日目にしてようやく明かされるこの真実。
ようやく5日目後半に作成したslugifyの動作原理がなんとなくわかったような気がしないでもありません。


ということでJobeetCategoryモデルに:slugなんてカラムは存在しないので、対応するgetメソッドを作成します。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
public function getSlug(){
  return Jobeet::slugify($this->getName());
}

Jobeet::slugify()は+や%といったURLとして表示するには美しくない文字をすべて削除します。
テンプレートからlink_to()した際のリンク先URLを勝手に書き換えてくれます。
メソッド自体は昔作成したので改めて実装する必要はありません。

しかし、このクラス名をいきなり書いたら何故か/lib/Jobeet.phpがインクルードされるというのが意味不明なのですが、これは一体何処から出てくるのでしょうか。
あとslugifyって何だ。


トップページからカテゴリへのリンクを作成します。
apps/frontend/modules/job/templates/indexSuccess.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!-- some HTML code -->
 
        <h1>
          <?php echo link_to($category, 'category', $category) ?>
        </h1>
 
<!-- some HTML code -->
 
      </table>
      <?php if (($count = $category->countActiveJobs() - 
        sfConfig::get('app_max_jobs_on_homepage')) > 0):
       ?>
        <div class="more_jobs">
          and <?php echo link_to($count, 'category', $category) ?>
          more...
        </div>
      <?php endif; ?>
    </div>
  <?php endforeach; ?>
</div>

どういうこと?

上半分は、既存テンプレートの
<h1><?php echo $category ?></h1><br />
の部分を差し替えます。

下半分は
</table><br />
以下を差し替えます。

こうすることでインデックスからカテゴリページへのリンクが表示されま、せん。
JobeetCategory::countActiveJobs()が実装されていないからです。
早速実装します。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
7
public function countActiveJobs(){
  return Doctrine_Query::create()
    ->from('JobeetJob j')
    ->addWhere('j.category_id = ?', $this->getId())
    ->addWhere('j.expires_at > NOW() ')
    ->count();
}

できました。
単に有効な求人件数を取得するというメソッドです。
結果として、有効な求人全てを表示できない場合に、カテゴリページへのリンクが作成されます。
link_to()の第二引数に'category'を与えると、ルーティングのcategory:url:に合致するように勝手にURLを組み立ててくれます。
まだ存在していないcategoryモジュールへのルーティングなんてものを先に設置しなければならなかった理由が、このlink_to()というわけです。


JobeetCategoryにJobeetJobの内容を書いてしまったので、例によって分割します。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
public function countActiveJobs(){
  $q= Doctrine_Query::create()
    ->from('JobeetJob j')
    ->addWhere('j.category_id = ?', $this->getId());
  return Doctrine::getTable('JobeetJob')->countActiveJobs($q);
}
lib/model/doctrine/JobeetJobTable.class.php
1
2
3
4
5
6
7
8
public function countActiveJobs(Doctrine_Query $q = null){
    if (is_null($q)){
      $q = Doctrine_Query::create()
        ->from('JobeetJob j');
    }
  $q->addWhere('j.expires_at > NOW() ');
  return  $q->count();
}

できました。


この状態で問題無いといえば問題無いのですが、JobeetJobTableクラスをよく見るとJobeetJobTable::getActiveJobs()JobeetJobTable::countActiveJobs()にほとんど同じコードが並んでいます。
効率よく纏めてしまいましょう。

lib/model/doctrine/JobeetJobTable.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class JobeetJobTable extends Doctrine_Table{
  /*
   *    現在有効なJobeetJobを一件だけ取得 
   */
  public function retrieveActiveJob(Doctrine_Query $q){
    return $this->addActiveJobsQuery($q)->fetchOne();
  }
 
  /*
   *     現在有効なJobeetJobを全件取得 
   */
  public function getActiveJobs(Doctrine_Query $q = null){
    return $this->addActiveJobsQuery($q)->execute();
  }
 
  /*
   *    現在有効なJobeetJobの件数を取得
   */
  public function countActiveJobs(Doctrine_Query $q = null){
    return $this->addActiveJobsQuery($q)->count();
  }
 
  /*
   *    DQLに現在有効なJobeetJobを追加
   */
  public function addActiveJobsQuery(Doctrine_Query $q = null){
    if (is_null($q)){
      $q = Doctrine_Query::create()->from('JobeetJob j');
    }
    $alias = $q->getRootAlias();
    $q->andWhere($alias . '.expires_at > NOW()')
      ->addOrderBy($alias . '.created_at DESC');
    return $q;
  }}

SQLを組み立てる部分と実行する部分を分けることにより、すっきりしたコードにすることができました。
ただORDER BYは本来そんなところに書くべきではないと思うのですが、Doctrineはcount()の際に不要なORDERとかを削除してくれるのでひとまずは問題ありません。

しかしgetRootAliasは突如出てきて一切説明無しですか。
動作から推測するに、$q->addWhere('j.expires_at > NOW() ');の'j'の部分を取得するメソッドのようです。
Doctrine_Hydrate::getRootAlias()で定義されているようですがヘルプが存在しねえ。


Symfonyの記事一覧


2010/01/11 20:18 | Comments(0) | TrackBack() | PHP
買ったものリスト 2010/01/10

どうでもいいが「こえでおしごと パスワード」でググって来る奴ってどうなんだろうね。
たかが一冊くらい買えよ。


文学少女見習いの傷心。
☆☆☆☆☆

野村美月って大昔に赤城山卓球場に歌声は響くって本を読んで、全然わけがわからねえ、という印象しか持てなかった記憶があるんだ。
なんか魔王とか出てなかったっけ。
で、夏頃になんとなく文学少女読んでみたらそのレベルの高さにびっくりしましたよ。
いつのまにかこんな本を書けるようになっちゃってまあ。
というわけで当時出ていた文学少女全部買いそろえました。

本作はようやく美羽の軛から解放されたと思いきやあんまり変わってない心葉の話。
登場人物がどいつもこいつも影や闇や裏や逆や対偶持ちの中、ほぼ唯一まっすぐな菜乃が清涼剤になっています。
そういえば確かにあの二人は直接会ってないからそういうトリックも有りではあるが、では何故そんなことをしたという動機がよく判らなかった。
あと最後のオチは一体どうやって収拾付けられるんだろうか。


デュラララ!!3
☆☆☆☆

だから言ったのに!
あまりにも予想通りの展開で逆にびっくりだ。
あと警察が格好良すぎる。

どうでもいいんだが、セルティが毎回PDAに…とか!とか入力する姿を想像するたびになんとなく吹く。
画面を見せるんじゃなくてテキスト読み上げ機能くらい付けてやればいいのにと思うんだがどうだろう。


論理少女3
☆☆☆☆

サイコロの高さはいつきの目線まであるので相当でかいのだが、そんな壁そうそう登れるものかね?
まあサイコロの一辺は1.5メートルとしよう。
天井の高さはサイコロ4つ分ほどなので約6メートル。
階段13段で高低差6メートルはどう考えても無理なのでこの時点でおかしいと気付くべき。

実は階段の半分は描写されていなかった等の理由で高低差6メートルがきちんと存在したと仮定する。
通路の幅としてはサイコロ5個分、迷路ブロック15個分なので迷路ブロックはサイコロの1/3の大きさ。
よって三角砦一辺の長さは長さはサイコロ約10個分となる。
と思いきや表示されている部分だけで最低12個分あったので、前後の余裕とかを見て一辺サイコロ15個分としよう。
すると三角砦一辺の長さは22.5メートル。
泥部分に傾斜は付けられないのでそのぶん短くなるはずですが、ここでは大幅に余裕を見てざっと一周100メートルとしよう。
そうすると傾斜角は6%となる。

公共施設などのスロープは傾斜角度5%以下にすること、という目安があります。
かの有名な碓氷峠は6.7%です。
つまり、6%の傾斜って見ればわかる。


ちばてつやとジョーの戦いと青春の1954日
☆☆☆☆

☆は資料性として。

あしたのジョー関連の掲載誌などの情報、そしてその漫画を書いていたときのちばてつや氏の心境などが時系列順に纏められています。
力石の葬儀が実際に行われるなどの社会現象にまでなったジョーですが、ちばてつやと梶原一騎がどのようにして本作を作り上げていったかということがわかって面白かったです。
終盤の梶原一騎ちょっとひどくねーかと思うようなこともありますが、「今まで散々変えてきたくせに今さらなんだ!任せる!」で全部許す。


ゲームサイドVol.22
☆☆☆☆

カプコンのFCソフト特集、ゲームウォッチ特集、萌え系ノベル特集。
今回も読ませる記事が多くて全部読むのが大変だ。
ただ個人的には発売前ゲーム記事は要らない。
ほしいと思ってもまだ発売されてないし、それに実際発売されてみたらアレだったということも多いからな。
やはり発売されて、実際にプレイしての赤裸々な感想を書いてこそのゲーサイだと思う。



2010/01/10 16:05 | Comments(0) | TrackBack() | 買ったもの
コメントを掲載せずにエア罵倒:DAKINI
このひとの特徴のひとつとして、
「コメントを掲載許可せずにその内容について罵倒」
というのがあります。

どう考えても常識的に有り得ない。

天国と地獄じゃなくて、地獄と地獄なんだよね。@さあのコメント欄一件目がまさにそれです。
誰もが「お前誰に向かって何を言ってんだ?」と思うところです。

たまたま被害者が全文をアップしてくれたので紹介してみたいと思います。

<被害者:エントリへのコメント:非掲載>

>任天堂は『脳トレ』以後、それを持続させるための新しいゲームを作れませんでした。
リズ天、トモコレはこれに当たるのでは?
累計販売本数で見ればFF最新作に対してリズ天が互角、トモコレは圧勝?
国内No2RPGに匹敵するソフトを2本も出せれば十分でしょう

>『Newマリオ』にしても、
>脳トレ層ではなくて、回帰層が購入している
>だけです。回帰層+子供ですよね。
任天堂が子供を獲得してきたおかげで今のゲーム業界は成り立っているのでは?
モンハンにしても膨大な数のポケモン卒業層を上手く掴んでヒットさせました
くねくねハニィさんの主旨も「任天堂が連れてきた新規客層への訴求不足」でしょう
今のサードは口をあけてライトゲーマーがゲーマーになるのを待ってるだけです
娯楽の多いこのご時世、勝手にゲーマーになってくれる人は極少ですよ

>北米における「マーベラスの惨劇」とでもいうべきか・・・・。
マベの惨劇なんて言ってるのはもうここくらいですよ
発言した当の本人が海外インタビューで例の発言に関して尋ねられ
呆れてたのをご存知ですか?

>一方、ゲーマーはより高品位の大作ゲームに集約されていきます。
>中堅タイトルはゲーマーが大作を遊ぶ合間の時間を奪い合って、競争をくり広げるのでしょうね。

>ちょっと勘違いされるとイヤなんですけど、
>別に僕は任天堂マーケットが地獄で、ゲーマー向けマーケットが天国だというつもりはありません。

>どっちも地獄は地獄。あとは、
>カジュアルユーザー地獄とゲーマー地獄、どちらの地獄がお好みですか、
>というだけに過ぎません。
この辺はまさにその通りですね。ゲーマー向けが天国なら
今世代のスタジオ閉鎖・解散のオンパレードと言う惨状は
避けられていたはずですから

任天堂が少し血を流して、クラコン同梱・スペックアップを図っていれば
「みんな」が集うゲーム機が出来てもおかしくなかったのですが

<DAKINI:コメントを非掲載の上返答>

熱狂的な人が懲りずに書き込んだので消しました。

それにしてもいまだに「マーベラスの惨劇」という現実を認められない人がまだいらっしゃるんですねえ。発言した当人が、話題の広がりっぷりに驚いて、あわててフォローする発言を出しただけ。

それで、あたかも「惨劇」が無かったことになったわけではありません。マーベラスのWii向けタイトルの売上が上がったわけではないし、HD向けのタイトルを増やす方針を変えたわけでもない。まあ現実から目をそらしたいのはわかりますが(苦笑

そういえば、任天堂のCM枠で、昨年後半に『朧村正』が流れましたけど、何か「外交」が働いたんでしょうか(笑 そういう事ですよね。任天堂が火消しさせただけ、という捉え方もできるでしょう。マーベラスも任天堂と「国交断絶」したいわけでもないし。

「マーベラスショック」を無かったことにしたいなら、マーベラスのWii向けソフトを買ってあげる運動でもしたらいいのでは?(苦笑 起きた現実は消せません。マーベラスしかり、セガオブアメリカしかり。

ちなみに「脳トレ」層は大部分マーケットから離れています。「リズム天国」も「トモコレ」も客層が違います。「トモコレ」は女児層が非常に強いですね。「どうぶつの森」、「ガールズモード」あたりの流れではありますね。マーケットの現実を見ましょう。

業界的には「トモコレ」も一過性のブームだという認識で、それこそ、「トモコレ」以後の定着ができるのだろうか、という点が注目されてるのだと思いますね。「脳トレ」ブームではユーザーの定着に失敗しており、「脳トレ」ブームに比べれば小規模とはいえ、「トモコレ」ではどうなるか。

まあ、熱狂的な人達は「サードパーティ批判」を好みますが、そういう熱狂的な人達がネットで暴れれば暴れるほど、任天堂オンリーマーケットという印象は強まっていくんじゃないでしょうか。どっちも地獄なのだとしたら、サードパーティがどちらを好むか。Wiiについては答えが出つつありますね(苦笑

Wii市場は、「サードパーティが居なくても大丈夫」という、一部の人達の極論が適切かどうかを検証する、興味深い「実験場」になりつつありますね。がんばって「任天堂機にはサードパーティは不要」と主張し続けてください。実験結果にはとても興味があります。非常に面白い。

<被害者:DAKINIのコメントへの返答:非掲載>

>それにしてもいまだに「マーベラスの惨劇」という現実を認められない人がまだいらっしゃるんですねえ。
>発言した当人が、話題の広がりっぷりに驚いて、あわててフォローする発言を出しただけ。

てんで的外れです。やっぱりご存じ無いようだ
該当の海外インタビューは発言後しばらくたってからの物ですし
市場の問題ではなく、過去含めて自分達の作り方・売り方の問題という発言ですよ?
そもそもマーベラスは10万売れるソフトをほとんど持っていないんですが?
売上的にみても昔から大差ありません。開発費高騰に苦しむ中堅てだけです

脳トレブームの定着も良く仰りますが
幅広い客層を生かしてピンポイントでも広いパイを使い、低コストで利益を出しています
マーケットの現実を見るならトモコレは"大人"の間で広がりを見せていますし
しかし一過性ですか。半年経って10万以上売れ続けるのが一過性とは変な話ですね

そもそもコメントを消しておいて一方的に攻撃するのは卑怯ですよね
>任天堂が子供を獲得してきたおかげで今のゲーム業界は成り立っているのでは?
>モンハンにしても膨大な数のポケモン卒業層を上手く掴んでヒットさせました
>くねくねハニィさんの主旨も「任天堂が連れてきた新規客層への訴求不足」でしょう
>今のサードは口をあけてライトゲーマーがゲーマーになるのを待ってるだけです
>娯楽の多いこのご時世、勝手にゲーマーになってくれる人は極少ですよ
この辺の発言は見なかった事にしたいようですし

自分の意見に自信がおありなら両方載せて他人の意見を聞いてみるといい
あなたの"クオリティコントロール"でコメントする人はかなり偏るようになりましたが

ひとつ言っておきますが、私は真面目に意見しています
勝手に熱狂的とレッテルを貼ったり馬鹿にするような発言で返すのは礼を失していますね
ゲーム業界の人には常識ない方が多いようですけど


どちらの主張の方が筋が通っているかは、各自で判断してみてください。

ちなみにマーベラスの惨劇とは
魂の叫び、切なる願い@王様物語クリエイターズBLOG
過ぎたるは及ばざるが如し@王様物語クリエイターズBLOG
の2本の記事のことです。
感想は読んだ人の意志に任せるとして、マベは海腹川背でやってしまったからいまいち信用しきれない。


2010/01/08 22:43 | Comments(0) | TrackBack() | 戯言
Symfony-6日目その3
その2で終わるかと思ってたらその3だよ。
 
チュートリアルは最初に表示の上限を設定するようになっていますが、こちらでは先にその下のフィクスチャから行います。
フィクスチャはYAMLでデータベースの中身を書いとけば下記コマンドでデータベースに内容を登録できるよ、というものです。
>php symfony doctrine:data-load

で、実はYAMLファイル内にPHPコードを書くことができます。

まずチュートリアルのjobs.ymlフィクスチャをコピーし、これまでの3つのjob_sensio_labs、job_extreme_sensio、expired_jobの下に追加。
上記コマンドを実行。
データベースを覗いてみると、さくっと34件のレコードが作成されています。
ブラウザから覗いてみると、期限切れになっていないレコードがだだーと33件表示されるはずです。

求人件数が100件とか1000件になったら非常に困るので、表示上限とページング処理が必要となります。
とりあえず表示上限を追加しましょう。
といっても単にLIMIT句を追加するだけですが。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
7
public function getActiveJobs($max = 10){
  $q = Doctrine_Query::create()
    ->from('JobeetJob j')
    ->where('j.category_id = ?', $this->getId())
    ->limit($max);
  return Doctrine::getTable('JobeetJob')->getActiveJobs($q);
}

$maxとlimitメソッドを追加しただけです。
この状態でリロードすると、カテゴリ毎の最大表示件数が10件になります。

テンプレートから呼び出しを行うときに、最大表示件数を追加します。

apps/frontend/modules/job/templates/indexSuccess.php
1
  <?php foreach ($category->getActiveJobs(10) as $i => $job): ?>

最大表示件数をテンプレートに直書きしてしまうのはよろしくないので、デフォルト値をapp.ymlに持たせ、テンプレートから呼び出すようにしましょう。

config/app.yml
1
2
3
all:
  active_days:          30
  max_jobs_on_homepage: 5

apps/frontend/modules/job/templates/indexSuccess.php
1
2
3
<?php foreach ($category->getActiveJobs(
   sfConfig::get('app_max_jobs_on_homepage')) as $i => $job):
?>

デフォルトの10件がmax_jobs_on_homepageの5件で上書きされ、カテゴリ毎の最大表示件数が5件になります。


さて、上記のようにチュートリアルではテンプレートの呼び出し側でデフォルト値を取得していますが、ここはgetActiveJobsに実装するのが意味的に正しいと思うんだがどうだろう。こんなかんじで。

lib/model/doctrine/JobeetCategory.class.php
1
2
3
4
5
6
7
8
public function getActiveJobs($max = null){
  if(!$max){$max=sfConfig::get('app_max_jobs_on_homepage');}
  $q = Doctrine_Query::create()
    ->from('JobeetJob j')
    ->where('j.category_id = ?', $this->getId())
    ->limit($max);
  return Doctrine::getTable('JobeetJob')->getActiveJobs($q);
}

さて、一覧では非表示にすることができた期限切れの求人ですが、↓のようにjob_show_user:ルーティングに直通でアクセスすると普通に見えてしまいます。
http://symfony.localhost/frontend_dev.php/job/a/b/3/c
実際は何度も作り直しているのでid=3は無いと思いますが、データベースから直接確認して行ってみてください。

その表示する部分のロジックはどんなだったか確認してみます。

apps/frontend/modules/job/actions/actions.class.php
1
2
3
public function executeShow(sfWebRequest $request){
  $this->job = $this->getRoute()->getObject();
}

なんだこれ。
ああ、昨日意味がわからんと投げたやつでしたか。
とりあえずこのURLはrouting.ymljob_show_userにひっかかるので、job_show_user:options:method_for_queryを追加します。

apps/frontend/config/routing.yml
1
2
job_show_user:
  options: { model: JobeetJob, type: object, method_for_query:  retrieveActiveJob }

JobeetJobTableに該当のメソッドを追加します。

lib/model/doctrine/JobeetJobTable.class.php
1
2
3
4
public function retrieveActiveJob(Doctrine_Query $q){
  $q->andWhere('a.expires_at > NOW()');
  return $q->fetchOne();
}

すると上記のURLで、期限が切れた求人は見えなくなりました。
めでたしめでたし。

……そのaってどこから来たの?
method_for_queryって何?


これを一日一時間で終わらせろとかどう考えても無理。
十分な時間なんて何処にもねえよ。


Symfonyの記事一覧


2010/01/08 22:40 | Comments(0) | TrackBack() | PHP

<<前のページ | HOME | 次のページ>>
忍者ブログ[PR]